API keys
Issue, reveal, and revoke the workspace-bound API keys your integrations use to read and write content.
API keys let your own application — a marketing site, a mobile app, a build script — call Clog's external API to fetch and update content. Each key is bound to one workspace and one creator (you, at create time). The key carries no permissions of its own; at request time it inherits whatever permissions you currently hold on the workspace.
This page covers issuing, naming, expiring, revealing, editing, and revoking keys from the API keys page. Open it from the workspace sidebar — you need api-keys:read to view the page and api-keys:write to create / edit / reveal / revoke.
The API keys page
The page lists every key in the workspace. Each row shows:
- Name — what you called the key when you created it.
- Prefix — the first ~18 characters of the key (e.g.
clog_live_AbCdEfGh). The full key never appears here. - Status badge — Active, Expired, or Revoked.
- Expires — when the key auto-expires (or "No expiry").
- Created — when the key was issued and by whom.
Filters at the top of the list:
- Search — match on name.
- Active / Revoked or expired / All — quick filter on status.
Create a key
Click Create API key. Fill in:
- Name — a human label. Pick something operational —
marketing-site-prod,mobile-app-ios,weekly-rss-job. Future you will thank present you. - Expires (optional) — set a date for the key to auto-expire, or leave as No expiry for a long-lived key.
Click Create. A confirmation screen titled Key created opens with the full plaintext key:
clog_live_AbCdEfGhIjKlMnOpQrStUvWxYz...This is the only time you'll see the full key. Copy it into your secret manager / .env.local / vault now. Closing the dialog without copying means you'll need to revoke this key and create a new one — Clog stores only a hash and a one-way-encrypted copy that the Reveal action can decrypt later (see below), but the dashboard list never shows the value again.
Use the Copy button on the dialog, then Done to close.
Reveal an existing key
If you lost a key but the row still exists, click Reveal on its row. After confirming, the dashboard fetches the plaintext value from the encrypted copy in the database and shows it. You can copy it again, then click Done.
The reveal endpoint AES-decrypts the stored ciphertext server-side; the key is never logged.
Reveal requires api-keys:write (same as create / edit / revoke). It works for active keys only — revoked or expired keys can't be revealed, and you should treat them as gone.
If your integration is broken because the key was lost, revoke and rotate (create a new key, swap it in, then revoke the old one) instead of revealing. Reveal exists for legitimate recovery, but a freshly-created key is better hygiene.
Edit a key
Click Edit on a row. You can change:
- Name — purely cosmetic, no impact on behaviour.
- Expires — extend, shorten, or clear (
No expiry).
You cannot change the key's value, prefix, or which workspace / user it's bound to — those are immutable. To "rotate" a key with a new value, you create a new key and revoke the old one.
Revoke a key
Click Revoke on a row. After confirming, the key stops working immediately on the next request — any in-flight request already mid-handler finishes normally.
Revocation is idempotent: re-revoking an already-revoked key is a no-op. Revoked keys remain on the list with a Revoked status badge so you have an audit trail. They can't be revealed, edited (apart from name / expiry tidying), or unrevoked — once revoked, a key is dead.
What a key can do
A key carries no permissions of its own. At request time:
- Clog hashes the incoming
X-API-Keyheader and finds the matching row. - It looks up the current
Membershipof the user who created the key, on the workspace the key is bound to. - The route's required permission (e.g.
posts:readforGET /external/posts) is checked against that membership's permission list.
This has three important consequences:
- Permission changes apply live. If someone removes
posts:writefrom your membership, your existing keys lose write access on the very next request — no re-issue needed. - Removing your membership disables your keys instantly. The
ApiKeyrows still exist; they just stop working. If a teammate leaves the workspace, every key they created stops authorising. - The owner's keys grant everything. As long as the creator is the owner, their keys carry every permission. If the owner is demoted via ownership transfer, their keys still work — the ex-owner is auto-granted every permission as a member — but a subsequent permission edit would cut them down.
For machine integrations, don't issue keys from your personal membership. Create a dedicated workspace member (a service-user Clog account like integrations@yourcompany.com), give it only the permissions the integration needs, and issue the keys from that account. When teammates come and go, production doesn't break.
Best practices
- Server-side only. Never embed a key in a browser bundle, a mobile app's resource files, or a public repo. The key grants the creator's full workspace permissions on the bound workspace — anyone who exfiltrates it can read (and potentially write) your content.
- One key per integration. Don't share
marketing-site-prodwithmobile-app-ios. Per-integration keys make rotation surgical and revocation low-risk. - Use expiry dates for short-lived needs. Audits, time-bounded experiments, contractor access. A key that expires by itself is one fewer thing to remember.
- Rotate periodically. Even without a leak, rotating production keys quarterly (create new → deploy → revoke old) keeps your keyring hygiene sharp.
- Name keys for what they do.
marketing-site-prod-2026Q2. Future-you on a Sunday at 11pm needs to know what each row protects.
What v1 doesn't do
For transparency, these are tracked as v1 out-of-scope:
- No
last_used_attracking. The dashboard doesn't show when a key was last used or how often. If you need that for audit, route the key through a proxy you control. - No per-key rate limit. Rate limiting is global to the API, not per-key.
- No IP allowlist. A leaked key works from anywhere until you revoke it.
Treat your keys as production secrets accordingly.
Related
- API → Authenticating requests — the developer side: what the
X-API-Keyheader looks like in code. - Members and permissions — keys inherit the creator's membership permissions, so reading this page matters too.
- Reference → Permissions — full permission vocabulary and per-endpoint gates.