Record Class MintedToken

java.lang.Object
java.lang.Record
co.ankatech.ankasecure.sdk.auth.MintedToken
Record Components:
token - the access token, held in a zeroizable, redacting wrapper
lifetime - how long the issuer said the token is good for; strictly positive

public record MintedToken(BearerToken token, Duration lifetime) extends Record
One ANKASecure access token together with the lifetime the issuer stated for it.

A lifetime, not a deadline

This carries expires_in as the server sent it, and deliberately does NOT convert it to an absolute instant. Converting requires a clock, and the clock that decides when this token stops being usable belongs to CachingTokenSource - which is injectable, so that expiry can be tested by moving time rather than by waiting for it. Computing the instant here, against whatever Instant.now() returns, would put the conversion on a second clock that the freshness decision cannot see. That is not a hypothetical: the first version of this record did exactly that, and the source it fed then treated every token as valid forever, because the two clocks disagreed by months.

The expiry comes from the platform, never from a claim the SDK read

expires_in is stated outright by the issuer, in the same response that carried the token. Nothing here parses a JWT to find out, and in particular nothing parses the EXTERNAL token a federated workload presented: that token is opaque to the SDK by design, and inferring a lifetime from it would mean believing a claim from an issuer the SDK does not verify.

  • Constructor Details

    • MintedToken

      public MintedToken(BearerToken token, Duration lifetime)
      Creates an instance of a MintedToken record class.
      Parameters:
      token - the value for the token record component
      lifetime - the value for the lifetime record component
  • Method Details

    • value

      public String value()
      Renders the token for the wire.

      Materialising a String is an unavoidable loss at the HTTP boundary - a header value is a String and the JVM cannot erase one - so it is done at the last possible moment and never stored.

      Returns:
      the token value
      Throws:
      IllegalStateException - if the token has already been cleared
    • toString

      public String toString()
      Redacted: the wrapper's own toString shows at most a six-character prefix.
      Specified by:
      toString in class Record
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. All components in this record class are compared with Objects::equals(Object,Object).
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • token

      public BearerToken token()
      Returns the value of the token record component.
      Returns:
      the value of the token record component
    • lifetime

      public Duration lifetime()
      Returns the value of the lifetime record component.
      Returns:
      the value of the lifetime record component