Skip to content

MintedKeys Class

The policy for the placement where the server mints its own keys and the custodian only protects them (UseKeysInProcess): it generates them, encrypts them to the custodian's key-encryption key, keeps the ciphertext in a shared ring, and rotates on schedule. No key names here - the server names what it creates.

C#
public sealed record MintedKeys : System.IEquatable<Abblix.Jwt.ExternalKeys.MintedKeys>

Inheritance System.Object → MintedKeys

Implements System.IEquatable<MintedKeys>

Remarks

This is the weaker of the two postures, and naming it at the call site is the point: the private half is unwrapped into process memory and stays there, so a compromised process yields the key itself rather than the ability to ask the custodian to sign while its credential lives. In exchange, signing runs in process, and the custodian is touched once per key rather than once per token. Choose CustodianHeldKeys when the key must never be in memory at all.

Properties

MintedKeys.AdoptedKeys Property

Keys the server already signs with, taken into an EMPTY ring so the move to minted keys does not change which key is producing on the day it happens. Normally set through AdoptExistingKeys(JsonWebKey[]) rather than written here.

C#
public System.Collections.Generic.IReadOnlyList<Abblix.Jwt.JsonWebKey> AdoptedKeys { get; init; }

Property Value

System.Collections.Generic.IReadOnlyList<JsonWebKey>

Remarks

Without this the ring starts empty, and a ring of one key has nothing to trail behind: the freshly minted key produces from its first second, so every client whose JWKS copy predates that second meets a token it cannot verify. An adopted key is dated one rotation period back, which is what makes it the active one while the minted key serves out its propagation window - the old key keeps signing, the new one is published, and the changeover happens once clients have had the window to fetch it.

Adoption happens only into an empty ring. That is what makes leaving the call in place harmless: once the ring holds anything the keys are never taken again, so a key that has since retired is not resurrected, and pods racing to adopt settle it the same way they settle minting - one insert wins and the rest drop what they built.

MintedKeys.ContentEncryptionAlgorithm Property

The JWE enc sealing an entry: how the key itself is encrypted.

C#
public string ContentEncryptionAlgorithm { get; init; }

Property Value

System.String

MintedKeys.EncryptionAlgorithm Property

The JWE key-management algorithm the minted encryption key uses, or null to mint no encryption key at all.

C#
public string? EncryptionAlgorithm { get; init; }

Property Value

System.String

Remarks

Name it when anything encrypts to this provider: it covers both the provider's own encrypted tokens and inbound JWE a client sent, such as an encrypted request object.

MintedKeys.KeepRetiredFor Property

How long a key is kept after it stops signing, before it leaves the ring. Null keeps it for one full rotation period, which is the safe reading of RotateEvery.

C#
public System.Nullable<System.TimeSpan> KeepRetiredFor { get; init; }

Property Value

System.Nullable<System.TimeSpan>

Remarks

This must outlast every token the key signed. Removing it early does not degrade anything gracefully: the key vanishes from /jwks and every unexpired token it signed stops verifying, which is why the default errs long rather than short. Set it explicitly only to say "no token of mine lives longer than this", and remember refresh tokens are signed too, not just access tokens.

MintedKeys.KeyEncryptionKeyName Property

The custodian's name for the key-encryption key. Its versions seal and open the ring's entries, and it is the only key the custodian holds for this placement.

C#
public string KeyEncryptionKeyName { get; init; }

Property Value

System.String

Remarks

It must be an ASYMMETRIC key. Sealing uses its public half in process, which is what keeps the wrap local and needs no custodian round-trip; a symmetric KEK has no public half and would require one. Both Vault Transit and Azure Key Vault provision RSA keys, so this costs nothing in practice.

MintedKeys.KeyWrapAlgorithm Property

The JWE alg sealing an entry: how its data-encryption key is wrapped under the KEK.

C#
public string KeyWrapAlgorithm { get; init; }

Property Value

System.String

MintedKeys.RotateEvery Property

How often a fresh key is minted. It sets the rotation grid: every pod derives the same period, and exactly one of them wins the insert for it.

C#
public System.TimeSpan RotateEvery { get; init; }

Property Value

System.TimeSpan

Remarks

A new key does not sign the moment it appears. It is published and verifiable for KeyRingOptions.KeyRolloverPropagation first, so a client whose JWKS cache is stale never meets a token signed by a key it lacks. Keep this comfortably larger than that window.

MintedKeys.RsaKeySize Property

The modulus size for a minted RSA key. Ignored when the algorithm asks for an elliptic curve.

C#
public int RsaKeySize { get; init; }

Property Value

System.Int32

MintedKeys.SigningAlgorithm Property

The JWS algorithm the minted signing keys use, which also decides what is generated.

C#
public string SigningAlgorithm { get; init; }

Property Value

System.String