com.yahoo.security.token.TokenDomain Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.security.token;
import java.util.Arrays;
import static com.yahoo.security.ArrayUtils.fromUtf8Bytes;
import static com.yahoo.security.ArrayUtils.toUtf8Bytes;
/**
* A token domain controls how token fingerprints and check-hashes are derived from
* a particular token. Even with identical token contents, different domain contexts
* are expected to produce entirely different derivations (with an extremely high
* probability).
*
* Since tokens are just opaque sequences of high entropy bytes (with an arbitrary
* prefix), they do not by themselves provide any kind of inherent domain separation.
* Token domains exist to allow for explicit domain separation between
* different usages of tokens.
*
* Fingerprint contexts will usually be the same across an entire deployment of a token
* evaluation infrastructure, in order to allow for identifying tokens "globally"
* across that deployment.
*
* Access check hash contexts should be unique for each logical token evaluation audience,
* ensuring that access hashes from an unrelated audience (with a different context) can
* never be made to match, be it accidentally or deliberately.
*
*/
public record TokenDomain(byte[] checkHashContext) {
public TokenDomain {
if (Arrays.equals(checkHashContext, TokenFingerprint.FINGERPRINT_CONTEXT)) {
throw new IllegalArgumentException("Fingerprint and check hash contexts can not be equal");
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TokenDomain that = (TokenDomain) o;
return Arrays.equals(checkHashContext, that.checkHashContext);
}
@Override
public int hashCode() {
return Arrays.hashCode(checkHashContext);
}
@Override
public String toString() {
return "'%s'".formatted(fromUtf8Bytes(checkHashContext));
}
public static TokenDomain of(String checkHashContext) {
return new TokenDomain(toUtf8Bytes(checkHashContext));
}
}