Class ClientAssertionSigner

java.lang.Object
co.ankatech.ankasecure.sdk.security.ClientAssertionSigner

public final class ClientAssertionSigner extends Object
Mints the RFC 7523 §2.2 client assertion that proves an actor's identity with a registered key pair instead of a shared secret.

The private key stays in this process. It is handed to a Nimbus JWSSigner at construction and is never exposed again: there is no accessor returning the key, and none returning the JWK it came from. That is the property this credential kind buys over a shared secret, so it is a property of this class rather than a promise made elsewhere. There is deliberately no overload handing a key to the transport - a transport that could sign would be a transport that holds keys, and every caller would then have to trust it not to log one.

A fresh assertion is minted on every sign(String) call, and there is no accessor returning "the current" assertion. The API shape is what prevents reuse. The server claims each jti exactly once, so an assertion cached and re-sent after a timeout is the client replaying its OWN credential: the first attempt may well have been received and its jti consumed before the response was lost. The retry is then refused with the same opaque 401 invalid_client as a bad key, and everyone reading the client's logs diagnoses a server fault. This matters most on retry, which is exactly where a caching optimisation looks harmless.

The audience is passed to sign(String), never derived here. A client computing it would be guessing at a value the server owns, and would stop authenticating the day a deployment's edge URL changed. The value to pass is the expectedAudience the deployment returned when the key was registered.

Usage


 JWK privateKey = JWK.parse(Files.readString(keyPath));
 ClientAssertionSigner signer = new ClientAssertionSigner(actorId, privateKey);
 AuthenticatedSdk sdk = factory.authenticateApplicationWithKeyPair(
         actorId.toString(), signer, expectedAudience);
 
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    The client_assertion_type form value that selects this credential kind at the token endpoint, as fixed by RFC 7523 §2.2.
  • Constructor Summary

    Constructors
    Constructor
    Description
    ClientAssertionSigner(UUID actorId, com.nimbusds.jose.jwk.JWK privateKey)
    Binds this signer to one actor and one private key.
  • Method Summary

    Modifier and Type
    Method
    Description
    sign(String audience)
    Mints a fresh assertion for the given audience.
    Returns a description that names the actor and the algorithm and reveals nothing about the key, so an accidental log statement cannot leak signing material.

    Methods inherited from class java.lang.Object

    equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • CLIENT_ASSERTION_TYPE

      public static final String CLIENT_ASSERTION_TYPE
      The client_assertion_type form value that selects this credential kind at the token endpoint, as fixed by RFC 7523 §2.2. Any other value is refused with 400 invalid_request.
      See Also:
  • Constructor Details

    • ClientAssertionSigner

      public ClientAssertionSigner(UUID actorId, com.nimbusds.jose.jwk.JWK privateKey) throws com.nimbusds.jose.JOSEException
      Binds this signer to one actor and one private key.
      Parameters:
      actorId - the actor UUID; it becomes both iss and sub, which the server requires to name the actor presenting the assertion
      privateKey - the actor's private JWK. It must carry private key material - a public-only JWK cannot sign - and its key type must be RSA or EC. The key is consumed here and never retained in a form this class can hand back.
      Throws:
      com.nimbusds.jose.JOSEException - if the key carries no private material, its key type or curve is one the platform does not admit, or no admissible signature algorithm can be resolved for it
      NullPointerException - if either argument is null
  • Method Details

    • sign

      public String sign(String audience) throws com.nimbusds.jose.JOSEException
      Mints a fresh assertion for the given audience.

      Every call produces a new jti and a new validity window. The returned assertion is for immediate use by a single request; see the class javadoc for why re-sending one is a replay of the caller's own credential rather than a retry.

      Parameters:
      audience - the expectedAudience this deployment returned when the key was registered. Passed rather than derived: a client computing it would be guessing at a value the server owns.
      Returns:
      the signed assertion in JWS compact serialization, to be sent as client_assertion
      Throws:
      com.nimbusds.jose.JOSEException - if the signature cannot be produced, or if the resulting assertion exceeds the length the verifier admits
      NullPointerException - if audience is null
      IllegalArgumentException - if audience is blank
    • toString

      public String toString()
      Returns a description that names the actor and the algorithm and reveals nothing about the key, so an accidental log statement cannot leak signing material.
      Overrides:
      toString in class Object