Class ApiKeyAuthenticator
- Namespace
- MailFathom.Infrastructure.Security.ApiKeys
- Assembly
- MailFathom.Infrastructure.dll
Judges the credential an MCP request presented against the API keys a deployment configured.
public sealed class ApiKeyAuthenticator
- Inheritance
-
ApiKeyAuthenticator
- Inherited Members
Remarks
The keys are resolved per request rather than cached, which is what the secret machinery already promises everywhere else: material rotated behind an unchanged reference reaches the next operation with no cache to invalidate and no restart to schedule. The schemes that ship today read a local file or an environment variable, and a future network-backed store caches inside its own adapter, so the cost stays where the policy for it lives.
Comparison never touches the material directly. Each side is reduced to an HMAC-SHA-256 digest under a key this process generates at construction and never publishes, and the digests are compared with FixedTimeEquals(ReadOnlySpan<byte>, ReadOnlySpan<byte>). Hashing first is what keeps the length of a presented credential from leaking: a fixed-time comparison is only fixed-time over equal lengths, and comparing raw material would answer "how long is the real key" to anyone willing to time it. The digest key is per process rather than configured, because nothing outside this process ever needs to reproduce a digest.
Every configured key is evaluated, including one already matched and one already expired. Stopping early would make the time a refusal takes depend on where in the list a key sits, and would make an expired key answer faster than an unrecognized one — which is exactly the distinction the single generic refusal exists to hide.
Constructors
- ApiKeyAuthenticator(ISecretReferenceResolver, TimeProvider, ILogger<ApiKeyAuthenticator>)
Initializes a new API key authenticator.
Methods
- AuthenticateAsync(IReadOnlyList<ConfiguredSecret>, string?, CancellationToken)
Judges the credential an
Authorizationheader carried.