feat(api-keys): restrict keys to source IP addresses
A key can be limited to IP addresses or CIDR networks (e.g. the Wabenhain server); a stolen key is useless from anywhere else. Requests from other addresses get 403 "not allowed for this IP" and a log line. The admin UI asks for the addresses when creating a key, warns when a key works from anywhere, shows the last source address and can take it over into the allowlist - changing the list needs no new key (PATCH /api-keys/:id). Also: a key can only carry scopes its creator holds. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
9ae1d96a32
commit
f1dc0de3e2
16 files changed
+463
-10
No files matched your search
@@ -12,6 +12,13 @@ export function createApiKey(input: CreateApiKeyInput): Promise<CreatedApiKey> {
|
||||
});
|
||||
}
|
||||
|
||||
export function updateApiKeyAllowedIps(id: string, allowedIps: string[]): Promise<ApiKey> {
|
||||
return apiFetch<ApiKey>(`/api-keys/${id}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify({ allowedIps }),
|
||||
});
|
||||
}
|
||||
|
||||
export function revokeApiKey(id: string): Promise<ApiKey> {
|
||||
return apiFetch<ApiKey>(`/api-keys/${id}/revoke`, { method: "POST" });
|
||||
}
|
||||
@@ -12,6 +12,10 @@ export interface ApiKey {
|
||||
createdByUserId: string | null;
|
||||
createdAt: string;
|
||||
lastUsedAt: string | null;
|
||||
/** Source address of the last use - handy for filling in the allowlist. */
|
||||
lastUsedIp: string | null;
|
||||
/** IP addresses / CIDR networks the key works from; empty = anywhere. */
|
||||
allowedIps: string[];
|
||||
expiresAt: string | null;
|
||||
revokedAt: string | null;
|
||||
}
|
||||
@@ -20,6 +24,7 @@ export interface CreateApiKeyInput {
|
||||
name: string;
|
||||
scopes: ApiKeyScope[];
|
||||
expiresInDays?: number;
|
||||
allowedIps?: string[];
|
||||
}
|
||||
|
||||
export interface CreatedApiKey {
|
||||
|
||||
Reference in new issue
Block a user