Skip to main content
Table of Contents

Interface IApiKeyStore

Namespace
Stratara.Abstractions.ApiKeys
Assembly
Stratara.Abstractions.dll

Issues, validates, and revokes API keys — the machine-to-machine authentication plane. Keys are stored hashed (never in plaintext) and flow through the same membership/permission plane as human sign-ins: a machine key acts as its own actor with tenant-scoped roles, a personal access token acts as its bound user.

public interface IApiKeyStore
Extension Methods

Remarks

Fail-closed validation: unknown, revoked, and expired keys all return null. The erasure sweeps (RemoveAllForTenantAsync(Guid, CancellationToken), RemoveAllForUserAsync(Guid, CancellationToken)) exist so tenant- and user-erasure flows can clear the key plane in one call.

Methods

GetForTenantAsync(Guid, CancellationToken)

Lists the tenant's keys (descriptors only — raw keys are unrecoverable).

Task<IReadOnlyList<ApiKeyDescriptor>> GetForTenantAsync(Guid tenantId, CancellationToken cancellationToken = default)

Parameters

tenantId Guid

The tenant whose keys to list.

cancellationToken CancellationToken

Token to observe while listing.

Returns

Task<IReadOnlyList<ApiKeyDescriptor>>

The tenant's keys; empty when none exist.

ImportAsync(ApiKeyImportRequest, CancellationToken)

Stores a machine key whose raw value the caller already holds — for setups where the key must be known before the store exists: container orchestration, CI provisioning, self-hosted bundles, end-to-end test hosts. Idempotent, so it can run on every boot.

Task<ApiKeyDescriptor> ImportAsync(ApiKeyImportRequest request, CancellationToken cancellationToken = default)

Parameters

request ApiKeyImportRequest

The import parameters, including the raw key.

cancellationToken CancellationToken

Token to observe while importing.

Returns

Task<ApiKeyDescriptor>

The stored descriptor — newly created, or the existing one on a repeat import.

Remarks

The supplied value must match ApiKeyFormat — generate it with CreateRawKey(). The shape requirement is load-bearing: stores keep the key's digest unsalted because a generated key carries 256 bits of entropy, and a hand-picked value would quietly invalidate that.

Importing a value that is already stored is a no-op that returns the existing descriptor. The stored key is never mutated — a differing name, role set, or expiry leaves the stored key as it is, so a changed configuration can neither escalate a key's roles nor extend its life unnoticed. Compare the returned descriptor when that matters. Nothing about the "shown once" guarantee of IssueAsync(ApiKeyIssueRequest, CancellationToken) changes: import returns no raw key, because the caller already has it.

Exceptions

ArgumentException

The raw key does not match the canonical format, or the name is empty.

InvalidOperationException

The key value is already stored for a different tenant, as a personal access token, or in a revoked or expired state — none of which an import may silently adopt.

IssueAsync(ApiKeyIssueRequest, CancellationToken)

Issues a new key. The returned RawKey is shown once and never persisted. Personal access tokens (a bound user) require the user to hold an active membership in the target tenant.

Task<IssuedApiKey> IssueAsync(ApiKeyIssueRequest request, CancellationToken cancellationToken = default)

Parameters

request ApiKeyIssueRequest

The issuance parameters.

cancellationToken CancellationToken

Token to observe while issuing.

Returns

Task<IssuedApiKey>

The raw secret plus the stored descriptor.

Exceptions

InvalidOperationException

A personal access token was requested for a user without an active membership in the tenant, or roles were supplied for a personal access token.

RemoveAllForTenantAsync(Guid, CancellationToken)

Removes every key bound to the tenant — the key-plane step of a tenant-erasure sweep.

Task RemoveAllForTenantAsync(Guid tenantId, CancellationToken cancellationToken = default)

Parameters

tenantId Guid

The tenant whose keys to remove.

cancellationToken CancellationToken

Token to observe while removing.

Returns

Task

RemoveAllForUserAsync(Guid, CancellationToken)

Removes every personal access token bound to the user — the key-plane step of a user-erasure sweep.

Task RemoveAllForUserAsync(Guid userId, CancellationToken cancellationToken = default)

Parameters

userId Guid

The user whose personal access tokens to remove.

cancellationToken CancellationToken

Token to observe while removing.

Returns

Task

RevokeAsync(Guid, CancellationToken)

Revokes a key; it never validates again.

Task RevokeAsync(Guid apiKeyId, CancellationToken cancellationToken = default)

Parameters

apiKeyId Guid

The key to revoke.

cancellationToken CancellationToken

Token to observe while revoking.

Returns

Task

ValidateAsync(string, CancellationToken)

Validates a presented raw key: hash lookup, then revocation and expiry checks.

Task<ApiKeyDescriptor?> ValidateAsync(string rawKey, CancellationToken cancellationToken = default)

Parameters

rawKey string

The presented plaintext key.

cancellationToken CancellationToken

Token to observe while validating.

Returns

Task<ApiKeyDescriptor>

The key's descriptor, or null for unknown/revoked/expired keys.