Global admin: all API keys with editing, archiving, filters, configuration history and usage log
Description
Summary
A global admin should see and edit every API key in the instance, not only their own. Deleting a key is replaced by archiving, so the key stays on the list. The list gets owner and status columns with matching filters, and the limit of 20 keys per user is removed. A key is configured before it is created. Every key gains a usage log and a configuration history, shown as tabs on the key's page.
Acceptance criteria
Access and archiving
-
A global admin sees and edits every API key in the instance, regardless of who created it.
-
Editing someone else's key never reveals its value.
-
The "Delete" action is replaced by "Archive". An archived key stays on the list, opens read only under the title "View API key", and stops authenticating API calls.
-
The limit of 20 keys per user is removed.
Creating a key
-
"Create" opens an empty form titled "Create API key". Nothing is created until the form is submitted.
-
Submitting creates the key with the entered settings and shows its value once, with a copy action. After that, only its fingerprint is shown.
-
Leaving the form before submitting creates nothing.
List
-
New "Status" column and filter: Scheduled / Active / Expired / Archived. The filter also offers "All" and defaults to Scheduled, Active and Expired, so archived keys are hidden until selected.
-
New "Owner" column and filter showing the creator's display name, not the account ID. The filter offers "All" plus every user who created a key in the instance.
-
Filters and sorting apply to the whole set of keys, and the results count and pagination reflect the filtered result.
-
"Usage count" counts only the calls the key was authorized for.
-
Statuses and the expired-date highlight are readable in dark mode.
Tabs
-
Three tabs are rendered above the API key form: "Configuration", "Usage", "History".
-
"Configuration" is the default tab and holds the key form. Apart from the rules in this ticket, its layout is unchanged.
-
"Usage" and "History" are disabled until the key is created. Both stay available for archived keys.
Usage log
-
Every Web API call made with a known key is logged with its time, IP, result and request dump, and shown on that key's "Usage" tab.
-
The result is "Authorized" or the reason the call was rejected: archived key, not yet valid, expired key, IP not allowed, missing privilege.
-
The Web API checks the key before validating the request, so calls with invalid input are logged too.
-
Calls with an unknown key are not logged, because they cannot be tied to a key. Neither are requests whose body, path or query parameters cannot be parsed (for example a non-numeric ID), because they are rejected before the key is checked.
-
Entries older than 7 days are removed by a cron job.
Configuration history
-
Creating, editing and archiving a key each record a version with its author, time and IP. Saving without changes records nothing.
-
The "History" tab lists the versions newest first, with the date, the change (Created / Edited / Archived), the author, the IP and a summary of the changed settings.
-
Expanding a version shows each changed setting before and after. For the first recorded version, it shows the initial settings.
-
Keys that exist before this change get one version holding their current settings. It is "Created" if the key was never edited, otherwise "Edited" at its last modification.
-
The list and the "Configuration" tab show the newest version.
How External Share does it (details in the code)
-
Usage log: the api_key_usage table (api_key_id, time, remote_ip, usage jsonb). It is written by ApiKeyService.registerKeyUsage, called from WebApiController after authentication, read through GET api/keys/usage/{id}, and pruned by ApiKeyUsageCleanupService (cron at 1:00, 7-day retention).
-
Configuration history: versioned api_key_config rows (created_by_id, remote_ip, creation_time, privileges, validity dates, allowed_ips, archived). The list reads the newest version, GET api/keys/history/{id} returns all of them, and archiving is a new version with archived = true.
Out of scope
-
Restoring an archived key (Unarchive) and permanently deleting keys.
-
"Created" and "Last used" columns.
-
Filtering by name or description.
-
Logging calls with an unknown key, and the HTTP status of authorized calls.
-
Exporting the list: AP-962.
-
Redesigning the form inside the "Configuration" tab: covered by the API key form redesign ticket.