personal-access-tokens
Long-lived, revocable Personal Access Tokens for headless HTTP-API access. Stores SHA-256 token hashes in the read_api_tokens direct-write table; the plaintext is returned once at creation. create/revoke/mine manage a user’s own tokens and available-scopes lists the app-declared scope catalog. Bearer tokens carrying the PAT prefix are resolved before jwt.verify (roles resolved live, granted scopes enforced fail-closed at the API boundary) — the resolver is wired via run-prod-app, not the dispatcher. Pass { toggleable: { default: false } } to tier-gate the whole feature.
Quick example
Section titled “Quick example”From apps-use-all-bundled — the smallest working mount:
// Smoke-entrypoint for use-all-bundled. CI runs this with// KUMIKO_DRY_RUN_ENV=boot to exercise validators across every bundled// feature without an actual postgres/redis. See package.json `boot`// script + ../README.md.
import { frameworkCoreEnvSchema, runProdApp } from "@cosmicdrift/kumiko-dev-server";import { InMemoryKmsAdapter } from "@cosmicdrift/kumiko-framework/crypto";import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";import { composeEnvSchema } from "@cosmicdrift/kumiko-framework/env";import { APP_FEATURES } from "../src/run-config";
const SMOKE_TENANT_ID = "00000000-0000-4000-8000-000000000001" as TenantId;
const envSchema = composeEnvSchema({ core: frameworkCoreEnvSchema, features: APP_FEATURES,});
await runProdApp({ features: APP_FEATURES, envSchema, // Smoke-only: exercises the hard PII boot gate + blind-index gate with // every bundled feature mounted. Real apps wire createPgKmsAdapter(...). kms: new InMemoryKmsAdapter(), blindIndexKey: Buffer.alloc(32, 7).toString("base64"), // migrations default ("./kumiko/migrations") — Boot-mode springt vor dem // Schema-Drift-Gate raus, der Pfad ist hier nur der runProdApp-Default. // auth.admin triggert composeFeatures(includeBundled:true) — auto-mounts // config + user + tenant + auth-email-password. Boot-mode exitiert // bevor admin-Seeding läuft, der Wert ist nur ein Stub für die Typen. auth: { admin: { password: "smoke-only-never-deployed", displayName: "Smoke Admin", memberships: [ { tenantId: SMOKE_TENANT_ID, tenantKey: "smoke", tenantName: "Use-All-Bundled Smoke", roles: ["TenantAdmin"], }, ], }, },});📄 On GitHub: samples/apps/use-all-bundled/bin/main.ts
How it fits
Section titled “How it fits”What this feature needs to run (Requires, top) and the write commands it provides (Provides, bottom).
flowchart TB
n_personal_access_tokens["personal-access-tokens"]
subgraph how_reqs["Requires"]
n_user["user"]
n_tenant["tenant"]
end
subgraph how_provides["Provides"]
n_cmd_personal_access_tokens_write_create(["create"])
n_cmd_personal_access_tokens_write_revoke(["revoke"])
end
n_user --> n_personal_access_tokens
n_tenant --> n_personal_access_tokens
n_personal_access_tokens --> n_cmd_personal_access_tokens_write_create
n_personal_access_tokens --> n_cmd_personal_access_tokens_write_revoke
Provides — write commands this feature registers (dispatch them through the command bus):
Getting started
Section titled “Getting started”Start with apps-use-all-bundled for a step-by-step walkthrough with runnable code and integration tests.