feat(auth.apikeys): add IApiKeyAdminStore.SetScopesAsync + SetEnabledAsync (editable scopes + reversible enable, no schema change); bump 0.1.3
This commit is contained in:
@@ -187,6 +187,53 @@ public sealed class ApiKeyAdminCommands
|
||||
return new KeyActionResult(deleted, status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set-scopes: replaces the scope set on an existing key WITHOUT touching its secret, and
|
||||
/// appends a <c>set-scopes</c> audit entry. Only the scope count is recorded in the audit
|
||||
/// details — the scope values themselves are not logged verbatim.
|
||||
/// All attempts are audited, including failures (key not found) — this is intentional to
|
||||
/// maintain a complete security trail.
|
||||
/// </summary>
|
||||
public async Task<KeyActionResult> SetScopesAsync(
|
||||
string keyId, IReadOnlySet<string> scopes, string? remoteAddress, CancellationToken ct)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(keyId);
|
||||
ArgumentNullException.ThrowIfNull(scopes);
|
||||
|
||||
bool updated = await _adminStore.SetScopesAsync(keyId, scopes, ct).ConfigureAwait(false);
|
||||
|
||||
string status = updated ? "scopes-set" : "not-found";
|
||||
// Record only the count, never the scope contents, to avoid leaking authority detail into audit.
|
||||
await AppendAuditAsync(keyId, "set-scopes", remoteAddress, $"{status}; count={scopes.Count}", ct)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return new KeyActionResult(updated, status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// enable-key / disable-key: reversibly toggles a key's active state WITHOUT changing its
|
||||
/// secret, and appends an <c>enable-key</c> (when enabling) or <c>disable-key</c> (when
|
||||
/// disabling) audit entry.
|
||||
/// All attempts are audited, including failures (key not found) — this is intentional to
|
||||
/// maintain a complete security trail.
|
||||
/// </summary>
|
||||
public async Task<KeyActionResult> SetEnabledAsync(
|
||||
string keyId, bool enabled, string? remoteAddress, CancellationToken ct)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(keyId);
|
||||
|
||||
DateTimeOffset now = _clock.GetUtcNow();
|
||||
bool updated = await _adminStore.SetEnabledAsync(keyId, enabled, now, ct).ConfigureAwait(false);
|
||||
|
||||
string eventType = enabled ? "enable-key" : "disable-key";
|
||||
string status = updated
|
||||
? (enabled ? "enabled" : "disabled")
|
||||
: "not-found";
|
||||
await AppendAuditAsync(keyId, eventType, remoteAddress, status, ct).ConfigureAwait(false);
|
||||
|
||||
return new KeyActionResult(updated, status);
|
||||
}
|
||||
|
||||
private string RequirePepper()
|
||||
{
|
||||
string? pepper = _pepperProvider.GetPepper();
|
||||
|
||||
Reference in New Issue
Block a user