Class PrivateKeyJwtTokenSource

java.lang.Object
co.ankatech.ankasecure.sdk.auth.CachingTokenSource
co.ankatech.ankasecure.sdk.auth.PrivateKeyJwtTokenSource
All Implemented Interfaces:
TokenSource, AutoCloseable

public final class PrivateKeyJwtTokenSource extends CachingTokenSource
Signs an RFC 7523 §2.2 assertion with a key pair this process holds and presents that.

The private key never leaves the caller: it lives inside the ClientAssertionSigner, which has no accessor that returns it. The platform holds only the public half, so it could not present this workload's identity even if it wanted to - which is the entire difference between this credential kind and a shared secret.

Every mint signs a new assertion, and caching one would be a self-inflicted replay

The server claims each jti exactly once. Re-sending an assertion - after a timeout whose request was in fact received, say - is the client replaying its own credential, and it is refused with the same opaque 401 invalid_client as a forged one. Everybody then reads the client's logs and diagnoses a server fault. Nothing here holds an assertion between calls; what is cached is the ACCESS TOKEN the assertion bought, which is a different object with a different lifetime and no replay semantics.

The audience is supplied, never derived

It is the expectedAudience the deployment returned when the key was registered. A client that computed it would be guessing at a value the server owns, and would stop authenticating the day a deployment's edge URL changed - as an authentication failure, which is the wrong place to start looking.

  • Constructor Details

    • PrivateKeyJwtTokenSource

      public PrivateKeyJwtTokenSource(co.ankatech.ankasecure.openapi.client.AnkaSecureOpenApiClient client, String clientId, ClientAssertionSigner signer, String expectedAudience)
      Parameters:
      client - the transport to mint against
      clientId - the actor UUID, sent as client_id
      signer - holds the private key; never asked for it
      expectedAudience - the value the deployment returned when the key was registered
      Throws:
      NullPointerException - if any argument is null
      IllegalArgumentException - if expectedAudience is blank
  • Method Details

    • mechanism

      public AuthMechanism mechanism()
      Description copied from interface: TokenSource
      Names the credential kind this source presents. Diagnostic only; nothing branches on it.
      Returns:
      the mechanism; never null
    • toString

      public String toString()
      Names the actor and the audience; the signer's own toString reveals no key.
      Overrides:
      toString in class Object