feat(auth.apikeys): add IApiKeyAdminStore.SetScopesAsync + SetEnabledAsync (editable scopes + reversible enable, no schema change); bump 0.1.3

This commit is contained in:
Joseph Doherty
2026-06-02 03:08:19 -04:00
parent 30c60f9d5f
commit 468959ca8a
7 changed files with 271 additions and 3 deletions
@@ -99,7 +99,10 @@ public interface IApiKeyStore { // default: SQLite (hash, scope
Task<ApiKeyRecord?> FindByKeyIdAsync(string keyId, CancellationToken ct);
Task MarkUsedAsync(string keyId, CancellationToken ct);
}
public interface IApiKeyAdminStore { /* create / revoke / rotate / delete + audit */ }
public interface IApiKeyAdminStore { /* create / revoke / rotate / delete + audit */
Task<bool> SetScopesAsync(string keyId, IReadOnlySet<string> scopes, CancellationToken ct); // 0.1.3: replace scope set; secret untouched
Task<bool> SetEnabledAsync(string keyId, bool enabled, DateTimeOffset whenUtc, CancellationToken ct); // 0.1.3: reversible enable/disable toggle; secret untouched
}
```
- Constraints are carried as an **opaque `object`** (project supplies the policy: mxaccessgw
@@ -107,6 +110,22 @@ public interface IApiKeyAdminStore { /* create / revoke / rotate / delete + audi
parse→lookup→peppered-HMAC→constant-time-compare→audit pipeline; it does **not** interpret constraints.
- Ships the `apikey` admin verbs as a reusable command set.
### 0.1.3 admin additions
`0.1.3` adds **editable scopes** and a **reversible enable/disable toggle** with **no schema
change** (still `CurrentVersion = 2`). Both land on `IApiKeyAdminStore` and the
`ApiKeyAdminCommands` facade:
- `IApiKeyAdminStore.SetScopesAsync(keyId, scopes, ct)` — replaces a key's scope set; never
touches the secret. Returns `false` if the key is unknown.
- `IApiKeyAdminStore.SetEnabledAsync(keyId, enabled, whenUtc, ct)` — clears (`enabled: true`) or
sets (`enabled: false`) `revoked_utc` regardless of current state; leaves `secret_hash` and
`last_used_utc` untouched (the distinction from rotate). Returns `false` if the key is unknown.
- `ApiKeyAdminCommands.SetScopesAsync(...)` — audited `set-scopes` verb (records scope **count**,
not contents); returns `KeyActionResult`.
- `ApiKeyAdminCommands.SetEnabledAsync(...)` — audited `enable-key` / `disable-key` verb;
returns `KeyActionResult`.
## `ZB.MOM.WW.Auth.AspNetCore`
- Canonical `ClaimTypes` constants (name, display, username, role, scope-id).