Skip to content

feat(oauth): issue the api key self-serve at app creation with abuse guardrails - #63

Merged
matthew-demidoff merged 1 commit into
masterfrom
feat/self-serve-api-keys
Aug 20, 2026
Merged

feat(oauth): issue the api key self-serve at app creation with abuse guardrails#63
matthew-demidoff merged 1 commit into
masterfrom
feat/self-serve-api-keys

Conversation

@matthew-demidoff

@matthew-demidoff matthew-demidoff commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Goal: create your own application without requiring admin approval. App creation already needed none for the OAuth client, but the activation-API key it minted was discarded, so a usable key required the admin-approved /request-bearer Telegram flow.

  • createAppAction returns the api key alongside the client secret (one-time display on the creation screen), gated by a verified email, a 5/hour per-user rate limit, and a cap of 10 active apps per owner; creation records an oauth_client_created security event.
  • The admin oauth-clients panel gains a live-application list with disable/enable via setExternalAppStatus - the first admin control over a live client. Apps the owner permanently revoked through the bearer flow are tagged and cannot be re-enabled, so an admin tidying the panel cannot silently resurrect a credential its owner believes dead.
  • Disabling an app now also kills its in-flight activation links: getActivationForUser/approveActivationForUser treat a non-active app as expired, so already-sent consent links stop working at disable time instead of surviving until their TTL.
  • In-product docs (/developers/oauth section 14.0, /request-bearer) now point at the self-serve path; the admin-review flow remains available.

Review attention and accepted tradeoffs:

  • Worst abuse story assessed: a verified burner account can mint consent links on the trusted domain at volume for phishing. The key cannot mint sessions, read data without per-user consent, or escalate scopes (activation scopes are hard-capped). Durable remediation is restricting the user (blocks creation and the bearer API); the panel makes per-app disable easy. A consent-screen caution for unreviewed apps and per-key volume limits are candidate follow-ups.
  • The per-user cap has a bounded TOCTOU (concurrent creations can overshoot to at most 14 before the next window blocks); the rate limit is consumed atomically first, so it is not worth a lock.
  • Owner-side key rotation lands separately in fix(oauth): rotate the api key alongside a shared pre-split client secret #61; together they give owners self-serve issue + rotate.

…guardrails

App creation minted an api key but discarded the plaintext, so a usable
activation-API key required the admin-approved /request-bearer flow.
Creation now returns the api key alongside the client secret (one-time
display), gated by a verified email, a 5/hour rate limit, and a cap of
10 active apps per user, and records an oauth_client_created security
event. The admin oauth-clients panel gains a live-application list with
disable/enable, the first admin control over a live client.
@matthew-demidoff
matthew-demidoff merged commit 98a0cdd into master Aug 20, 2026
2 checks passed
@matthew-demidoff
matthew-demidoff deleted the feat/self-serve-api-keys branch August 20, 2026 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant