Skip to content

feat(api-keys): support runtime key creation - #87

Open
workos-tars[bot] wants to merge 1 commit into
mainfrom
tars/feat-3028-runtime-api-keys
Open

feat(api-keys): support runtime key creation#87
workos-tars[bot] wants to merge 1 commit into
mainfrom
tars/feat-3028-runtime-api-keys

Conversation

@workos-tars

@workos-tars workos-tars Bot commented Aug 27, 2026

Copy link
Copy Markdown

Summary

  • add organization- and user-scoped API key creation
  • add user-scoped listing and API key expiration
  • register created keys in the live auth allow-list
  • complete API Keys coverage in SUPPORTED.md

Tracks FEAT-3028.

Validation

  • bun test src/workos/routes/api-keys.spec.ts src/workos/seed-m2m.spec.ts src/workos/response-envelopes.spec.ts
  • bun run typecheck
  • bun run lint
  • bun run fmt:check

Requested by garen.torikian@workos.com via TARS

@linear-code

linear-code Bot commented Aug 27, 2026

Copy link
Copy Markdown

FEAT-3028

@workos-tars

workos-tars Bot commented Aug 27, 2026

Copy link
Copy Markdown
Author

The x64 smoke probe repeatedly received connection resets; all other #87 checks passed. The same code also passed x64 Docker on stacked PR #88, so this appears transient rather than change-related.

GitHub rejected both the direct rerun and retry push, and no remote state changed. PR #87 remains blocked on the original failed check. A maintainer needs to select Re-run failed jobs on the workflow run.

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds organization- and user-scoped runtime API-key creation, user-scoped listing, expiration, and live authentication registration.

  • Adds create, list, and expiration handlers with owner and membership validation.
  • Synchronizes created and expired credentials with the authentication allow-list.
  • Updates API-key endpoint coverage and support documentation.

Confidence Score: 3/5

This PR should not merge until deleting a user or organization also revokes its runtime-created API keys.

The new routes place owner-linked secrets in the live authentication allow-list, but both owner-deletion paths leave those entries intact, so credentials for deleted principals continue to authorize requests.

Files Needing Attention: src/workos/routes/api-keys.ts, src/workos/routes/users.ts, src/workos/routes/organizations.ts

Security Review

Runtime-created credentials are not revoked when their owning user or organization is deleted, allowing orphaned keys to continue authenticating protected requests.

Important Files Changed

Filename Overview
src/workos/routes/api-keys.ts Adds runtime key lifecycle routes, but newly owner-linked credentials are not integrated with owner-deletion cleanup.
src/core/middleware/auth.ts Correctly treats an expiry equal to the current time as expired.
src/workos/routes/api-keys.spec.ts Covers creation, listing, expiration, and authentication, but not revocation after owner deletion.
scripts/gen-supported-lib.ts Updates the generated support note to reflect runtime-created credentials.
SUPPORTED.md Records the newly implemented API-key endpoint coverage.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Create API key] --> B[API-key record]
  A --> C[Live authentication map]
  D[Delete user or organization] --> E[Delete owner and existing cascades]
  E -. missing cleanup .-> B
  E -. missing revocation .-> C
  C --> F[Orphaned key still authenticates]
Loading
Prompt To Fix All With AI
### Issue 1
src/workos/routes/api-keys.ts:47-52
**Owner deletion leaves credentials**

When a user or organization owning a runtime-created API key is deleted, the deletion cascades remove neither the key record nor its live allow-list entry, causing the orphaned key to continue authenticating protected requests. The creation path needs corresponding owner-deletion cleanup for both stores.

**How this was verified:** The owner-deletion handlers omit both `apiKeyRecords` and `apiKeyMap`, while authentication continues accepting every unexpired entry retained in that map.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat(api-keys): support runtime key crea..." | Re-trigger Greptile

Comment on lines +47 to +52
permissions: (body.permissions as string[] | undefined) ?? [],
last_used_at: null,
expires_at: (expiresAt as string | undefined) ?? null,
});
const apiKeyMap = store.getData<ApiKeyMap>(STORE_KEYS.apiKeyMap) ?? {};
apiKeyMap[value] = { environment, expiresAt: record.expires_at };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Owner deletion leaves credentials

When a user or organization owning a runtime-created API key is deleted, the deletion cascades remove neither the key record nor its live allow-list entry, causing the orphaned key to continue authenticating protected requests. The creation path needs corresponding owner-deletion cleanup for both stores.

How this was verified: The owner-deletion handlers omit both apiKeyRecords and apiKeyMap, while authentication continues accepting every unexpired entry retained in that map.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/workos/routes/api-keys.ts
Line: 47-52

Comment:
**Owner deletion leaves credentials**

When a user or organization owning a runtime-created API key is deleted, the deletion cascades remove neither the key record nor its live allow-list entry, causing the orphaned key to continue authenticating protected requests. The creation path needs corresponding owner-deletion cleanup for both stores.

**How this was verified:** The owner-deletion handlers omit both `apiKeyRecords` and `apiKeyMap`, while authentication continues accepting every unexpired entry retained in that map.

**Knowledge Base Used:**
- [State storage and seed data](https://app.greptile.com/workos/-/custom-context/knowledge-base/workos/emulate/-/docs/state-storage-and-seeding.md)
- [Organizations, users, and memberships](https://app.greptile.com/workos/-/custom-context/knowledge-base/workos/emulate/-/docs/organizations-users-and-memberships.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid and already fixed locally in commit 95ed139:

  • Revokes user-owned keys when deleting a user.
  • Revokes organization- and member-owned keys when deleting an organization.
  • Removes both stored records and live authentication entries.
  • Adds regression coverage; 69 focused tests pass.

This Greptile comment still targets remote SHA 5a12133 because GitHub rejected TARS’s push. PR #87 remains unchanged; a verified human follow-up is required before TARS can retry publishing the fix.

@workos-tars

workos-tars Bot commented Aug 27, 2026

Copy link
Copy Markdown
Author

Local commit 95ed139 removes both API-key records and live allow-list entries when:

  • A user is deleted.
  • An organization is deleted, including user-owned keys scoped to that organization.

GitHub rejected the push with HTTP 403. PR #87 therefore remains at 5a12133; no remote state changed, and the review finding is not yet resolved on the PR. A verified human follow-up is needed for TARS to retry the push and update the stacked PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

0 participants