API Keys

Central API key model, scope ownership, and resource binding behavior across Topolo services.

publicverified 2026-08-01api-keyssecurityplatform

Ownership

API key records, scope definitions, canonical workspace identity, and resource-binding decisions are centrally served by Topolo Auth. Topolo Developers publishes application resource-type metadata, while the shared @topolo-io/api-key-management package owns the management UI and consumes Auth through the shared Auth client. Applications must not maintain local scope catalogs, workspace identity copies, API-key forms, or management proxy routes.

TopoloOne and Topolo Developers expose multi-application views for organization-wide credential administration. Every authenticated browser application also exposes the same shared application-mode screen from the account menu, limited to that application's service identity.

Key model

Each key has:

  • an owning organization
  • a target service
  • an explicit scope set
  • optional resource bindings
  • lifecycle state such as active or revoked

Resource bindings

Some services support resource-level constraints. First-party applications use the canonical Auth-owned workspace resource even when the product calls it a brand, project, venue, merchant, or another domain term. Auth validates requested bindings at key creation and update time.

Before rendering a key form or planning a key mutation, clients call api_keys.options for the selected application in the active organization. The response is user-specific and contains the only scopes and resources the caller may bind. Resource rows include the caller's accessLevel and allowedScopes; duplicate resource-type declarations are collapsed into one selector.

Applications must not inject their own workspace, brand, project, or other resource lists into the API-key UI. Auth queries its canonical active workspaces for the exact application and organization, then applies the same ownership and grant policy used for protected workspace requests. This prevents stale app-local lists or resources from another organization appearing in the form.

Consumer modes

  • Application mode: the current app supplies its canonical app ID and organization context. The shared screen shows only that app's keys, scopes, and bindable resources.
  • Multi-application mode: TopoloOne and Topolo Developers supply the organization's Auth-backed service catalog. Users can select an application and manage credentials across the organization.

Current consumer flow

  1. The host application supplies organization context and either one service or an Auth-backed service list.
  2. The shared screen requests api_keys.options from Auth for the selected service and exact active organization.
  3. The user selects zero or more authorized resources, then selects scopes from the intersection allowed across those resources. With no resource binding, only organization-wide scopes are available.
  4. Auth repeats the same authorization calculation for create and update requests; browser state is never authoritative.
  5. Auth re-evaluates the key owner's current application, organization, ownership, and grant access during introspection. Revoked or reduced access immediately narrows or invalidates the key.

Access levels

  • A workspace owner receives the application's read and write API-key scopes for that owned workspace, excluding management scopes.
  • A read_write workspace grant receives read and write scopes, excluding admin or management scopes.
  • A read workspace grant receives read scopes only.
  • Organization roles remain bounded to workspaces they own or have been explicitly granted. Platform operators authenticated through the Auth admin organization may inspect and bind all active workspaces in an explicitly selected organization with management scopes.
  • A key bound to multiple resources receives only scopes allowed by every selected resource.
  • Users manage their own keys. Holders of Auth's api_keys:admin permission may list and revoke other users' keys but cannot edit them.

Operational note

Resource-binding catalogs and key mutations are centralized in Auth. Reusable presentation and interaction behavior belongs in @topolo-io/api-key-management; app-local code should only provide identity, organization context, permissions, and placement.

Change Log / Verification

  • Corrected the public resource-binding model on 2026-07-29: Auth derives bindable resources directly from canonical workspaces rather than refreshing an app-owned provider or reading a shadow resource catalog (topolo-platform staging 8e4879af38ea).

  • Reconciled API-key discovery through topolo-platform origin/staging 51ff2d839e86 on 2026-07-29: static actions remain permission-filtered, while runtime-authorized actions are discoverable and re-authorized by their target for the concrete request.

  • Reconciled this page against topolo-platform origin/staging 24c646847b23 on 2026-07-24 after reviewing every docs-relevant commit since its previous verification watermark. Dependency-only currency commits were checked by the fleet production-dependency gate and did not change this page's product contract.

  • Added the user-specific api_keys.options preflight, ownership/grant scope caps, exact-organization resource filtering, duplicate resource-type deduplication, own-key lifecycle, and dynamic introspection enforcement on 2026-07-14.

  • Added clean-room agent resource-type discovery and identifier-resolution guidance on 2026-07-14.

  • Standardized API-key management on 2026-07-12: TopoloOne and Topolo Developers use the shared multi-application screen, every authenticated browser application's account menu opens the AppShell-owned app-local mode, and obsolete hand-built browser clients and proxy routes were removed.

  • Reconciled docs freshness on 2026-06-28 against topolo-platform through 20653c79; latest commit reviewed was 20653c79 feat(auth): bulk availability + app_id-mapping endpoints (seed subrequest cap), with recent context 20653c79 feat(auth): bulk availability + app_id-mapping endpoints (seed subrequest cap); 61117a0d feat(app-shell): add lazy component factory; d8784cfa feat(app-shell): add canonical lazy route factory.