Authentifizierung und scoped API-Keys
Scoped API-Keys (§1.5) - wie Sie Keys erstellen, der Katalog mit 27 Scopes, Scope-Hierarchie, Rotation und der /whoami-Endpoint zur Introspektion.
Jede Anfrage an die CodeCourier-REST-API authentifiziert sich mit einem scoped Projekt-API-Key. Jeder Key trägt eine explizite Allow-Liste von einem oder mehreren Scopes (siehe Katalog unten). Der Server lehnt Anfragen, deren Scope auf dem Key nicht vorhanden ist, mit einer Antwort 403 SCOPE_DENIED im v2-Error-Envelope ab (siehe Fehler).
Einen Key erstellen
Im Dashboard: Projekteinstellungen → API-Keys → Generieren. Geben Sie dem Key einen Namen (z. B. ci-pipeline) und aktivieren Sie die benötigten Scopes. Das vollständige Secret wird genau einmal angezeigt - kopieren Sie es sofort in Ihren Secret-Manager.
Programmatische Erstellung:
curl
curl -X POST https://<your-deployment>.convex.site/api/v1/project/api-keys/generate \
-H "Authorization: Bearer cc_live_<owner-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-pipeline",
"scopes": ["runs:read", "runs:write", "workflows:read"]
}'TypeScript (fetch)
const res = await fetch(
"https://<your-deployment>.convex.site/api/v1/project/api-keys/generate",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.CC_OWNER_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "ci-pipeline",
scopes: ["runs:read", "runs:write", "workflows:read"],
}),
}
);
const { data } = await res.json();
console.log(data.key); // cc_live_... - shown oncePython (requests)
import os, requests
res = requests.post(
"https://<your-deployment>.convex.site/api/v1/project/api-keys/generate",
headers={
"Authorization": f"Bearer {os.environ['CC_OWNER_KEY']}",
"Content-Type": "application/json",
},
json={
"name": "ci-pipeline",
"scopes": ["runs:read", "runs:write", "workflows:read"],
},
)
print(res.json()["data"]["key"]) # shown onceDer Katalog mit 27 Scopes
Scopes folgen dem Muster resource:action. read umfasst list + get; write umfasst create + update + delete.
- Projects:
projects:read,projects:write - Workflows:
workflows:read,workflows:write - Runs:
runs:read,runs:write,runs:cancel - Personas:
personas:read,personas:write - Issues:
issues:read,issues:write - Sandboxes:
sandboxes:read,sandboxes:write,sandboxes:exec - Contexts:
contexts:read,contexts:write - Assets:
assets:read,assets:write - Learnings:
learnings:read,learnings:write - Cost Rates:
cost-rates:read,cost-rates:write - Recurring Tasks:
recurring-tasks:read,recurring-tasks:write - Webhooks:
webhooks:read,webhooks:write - Team:
team:read,team:write - Meta:
*(Vollzugriff - sparsam einsetzen)
Scope-Hierarchie
*erfüllt jede Scope-Prüfung. Reservieren Sie diesen Scope für Owner-Level-Automatisierungen.resource:writeimpliziert nichtresource:read. Vergeben Sie beide ausdrücklich, wenn der Aufrufer vor dem Mutieren listen muss.- Vor §1.5 erstellte Legacy-Keys wurden mit
*übernommen - auditieren und über/whoamiverschärfen.
/whoami - Key-Introspektion
GET /api/v1/whoami liefert die Identität und die aktiven Scopes des aktuellen Keys zurück. Nützlich für CI-Preflight-Checks.
curl
curl https://<your-deployment>.convex.site/api/v1/whoami \
-H "Authorization: Bearer cc_live_..."TypeScript
const r = await fetch(
"https://<your-deployment>.convex.site/api/v1/whoami",
{ headers: { "Authorization": `Bearer ${key}` } }
);
const { data } = await r.json();
// { keyId, projectId, name, scopes: [...], createdAt, lastUsedAt }
if (!data.scopes.includes("runs:write")) throw new Error("scope missing");Python
import requests
r = requests.get(
"https://<your-deployment>.convex.site/api/v1/whoami",
headers={"Authorization": f"Bearer {key}"},
)
data = r.json()["data"]
assert "runs:write" in data["scopes"], "scope missing"Rotation
- Erzeugen Sie einen neuen Key mit denselben (oder strengeren) Scopes.
- Rollen Sie den neuen Key in Ihre Runtime aus; warten Sie einen vollständigen Anfragezyklus ab.
POST /api/v1/project/api-keys/revokeauf dem alten Key ausführen.- Bestätigen Sie, dass der widerrufene Key
401 unauthorizedzurückgibt.
Auditieren Sie die Nutzung über lastUsedAt - Keys, die 90+ Tage ungenutzt sind, sollten widerrufen werden.