AUTH
SERVICE CONTRACT · VIEW: GOV
Axiom
AUTH gates scope access. GitHub identity is KYC anchor. Scope-level readers/writers.
Constraints
MUST: GitHub account identity as sole KYC anchor MUST: Scope-level access — readers/writers declared in each scope's CANON.md MUST: Fail-closed — PRIVATE scope with no matching reader = deny MUST: Session tokens server-side (KV-backed, not client-only) MUST: Ledger all auth events via append-only chain (login, logout, grant, deny) MUST: Hash-chain integrity on auth ledger (id + prev per entry) MUST: Auth events are INTEL — backpropagate to LEARNING.md MUST NOT: Store GitHub tokens in client localStorage MUST NOT: Use loose KV keys for auth events — append-only ledger only MUST NOT: Gate public (SHOP) projections MUST NOT: Hardcode user lists outside CANON.md MUST: Every surface with privacy: PRIVATE declares auth: required in frontmatter MUST: Compiler validates: CANON.md privacy: PRIVATE → page has auth: required MUST NOT: Serve PRIVATE content without authenticated session
Capabilities
AUDIT_LEDGER, FAIL_CLOSED, GITHUB_OAUTH, SCOPE_GATING, SESSION_MANAGEMENT
COVERAGE: 255/255
SPEC
Purpose
AUTH is the gate. GitHub identity in, session token out. Every scope access checked. Fail-closed.
AUTH controls who sees what. GitHub OAuth provides the identity anchor (KYC). Sessions live in Cloudflare KV. Scope grants are resolved at query time from CANON.md readers and writers fields. Public content passes freely. Private content requires a valid session with matching grants. No session, no access.
Structure
Root AUTH domains: none currently (leaf service scope).
Required closure artifacts per scope:
CANON.md, README.md, AUTH.md, VOCAB.md, ROADMAP.md, COVERAGE.md, LEARNING.md.
Learning lane per governed scope:
LEARNING.md at the scope root is terminal and SHALL NOT nest further LEARNING/.
Routes
POST /auth/github Exchange GitHub OAuth code for session token
GET /auth/session Validate session token, return user identity
POST /auth/logout Delete session from KV
GET /auth/grants Check if session user can access scope X
Session Contract
{
user: GitHub username (KYC anchor)
github_uid: GitHub numeric user ID
org: hadleylab (ORG membership = permission boundary)
scopes_granted: [] (resolved at query time from CANON.md readers)
ts: session creation timestamp
expires: session expiry timestamp
}
Gate Logic
IF privacy = PUBLIC (or omitted) → no gate, everyone sees it
IF privacy = PRIVATE:
IF readers = * → all authenticated users
IF readers declared → check session.user against readers list
IF no readers declared → ORG members only (fail-closed to public)
writers: → same pattern, controls write/contribute access
CANON.md Extension
Any scope’s CANON.md MAY declare:
privacy: PRIVATE
readers: iDrDex, yanabeda, ir4y
writers: iDrDex
github: username
Fields:
privacy:— PUBLIC (default) or PRIVATEreaders:— comma-separated GitHub usernames granted read accesswriters:— comma-separated GitHub usernames granted write/contribute accessgithub:— on USER principal CANON.md, binds identity to GitHub account
Ecosystem Connectivity
- Upstream:
SERVICESgovernance contracts andhadleylab-canonicscope inheritance. - Runtime: Cloudflare Worker (api.canonic.org) + TALK_KV for sessions.
- Frontend: DESIGN.js auth flow, talk.js auth headers, magic.js scope gating.
- Ledger plane: all auth events (login, grant, deny) ledgered to TALK_KV.
Pages
| Page | Sections |
|---|---|
| Overview | Purpose, Structure |
| Routes | Routes, Session Contract, Gate Logic |
| Ecosystem | CANON.md Extension, Ecosystem Connectivity |
Default: Overview.
INTEL
Auth Architecture
| Component | Technology | Status |
|---|---|---|
| OAuth provider | GitHub | ACTIVE |
| Session store | Cloudflare KV (TALK_KV) | ACTIVE |
| API endpoint | api.canonic.org (Cloudflare Worker) | ACTIVE |
| Frontend | DESIGN.js auth flow + talk.js headers | ACTIVE |
API Routes
| Route | Method | Purpose |
|---|---|---|
| /auth/github | POST | Exchange GitHub OAuth code for session token |
| /auth/session | GET | Validate session, return user identity |
| /auth/logout | POST | Delete session from KV |
| /auth/grants | GET | Check scope access for session user |
Principal Registry
| Principal | GitHub | KYC Status | Scope Grants |
|---|---|---|---|
| DEXTER | iDrDex | VERIFIED | * (all scopes) |
| YANA | yanabeda | VERIFIED | BAKEOFF, MAGIC |
| ILYA | ir4y | VERIFIED | BAKEOFF, MAGIC |
| ISABELLA | TBD | PENDING | CLINICAL, DEAL, CALENDAR |
| JP | TBD | PENDING | DEAL, REAL_ESTATE |
| AVINASH | TBD | PENDING | CLINICAL, DEAL |
Gate Logic Intelligence
| Pattern | Rule | Enforcement |
|---|---|---|
| PUBLIC (default) | No gate | Everyone sees it |
| PRIVATE + readers=* | Auth required | All authenticated users |
| PRIVATE + readers declared | Auth + grant | Session user in readers list |
| PRIVATE + no readers | ORG only | Fail-closed to public |
Risk Assessment
| Risk | Severity | Mitigation |
|---|---|---|
| GitHub OAuth token compromise | HIGH | Short-lived tokens + KV session rotation |
| Scope grant creep | MEDIUM | Periodic reconciliation with KYC |
| Unregistered principal access | LOW | Fail-closed (ORG members only default) |
| KV session store failure | MEDIUM | Graceful degradation to public-only |
Test
| prompt | expect | cross |
|---|---|---|
| What OAuth provider anchors identity? | GitHub | VITAE |
| What is the default gate for unregistered principals? | fail-closed,ORG | |
| Where are sessions stored? | Cloudflare KV,TALK_KV | TALK |
| What API route validates a session? | /auth/session | |
| How does the gate logic handle PRIVATE scopes with no readers? | fail-closed,ORG |
Secret Rotation Playbook
| Secret | Location | Rotation Cadence | Procedure |
|---|---|---|---|
| CLOUDFLARE_API_TOKEN | Cloudflare Dashboard | 90 days | Profile → API Tokens → Roll → update Worker secrets |
| CLOUDFLARE_DNS_TOKEN | Cloudflare Dashboard | 90 days | Profile → API Tokens → Roll → update .env |
| STRIPE_SECRET_KEY | Stripe Dashboard | 90 days | Developers → API Keys → Roll → update Worker secrets |
| STRIPE_WEBHOOK_SECRET | Stripe Dashboard | 90 days | Developers → Webhooks → Roll signing secret |
| GOV_TOKEN | GitHub Settings | 90 days | Developer Settings → Fine-grained tokens → Regenerate |
| GITHUB_CLIENT_SECRET | GitHub Settings | 90 days | Developer Settings → OAuth Apps → Generate new secret |
| ANTHROPIC_API_KEY | Anthropic Console | 90 days | Settings → API Keys → Create new → revoke old |
| RESEND_API_KEY | Resend Dashboard | 90 days | API Keys → Create new → revoke old |
| Ed25519 vault keys | ~/.canonic/VAULT/ | 365 days | vault keygen –rotate → vault key-status checks age |
| VAULT_KEY_PASSPHRASE | Environment only | 365 days | Generate new passphrase → re-encrypt keys |
Enforcement: CI gate key-status checks Ed25519 key age (365-day window). API token age is not currently automated — track via calendar.
LEARNING
ROADMAP
Now
Later
VOCAB
| Term | Definition |
|---|---|
| KV | Cloudflare Workers KV — key-value store for sessions and ledger data. |
| KYC | Know Your Customer — GitHub account = identity anchor. |
| PRIVATE | Access-restricted scope — requires AUTH session with matching scope grant. |
| SHOP | Public projection — SHOP-safe content visible without authentication. |
INHERITANCE CHAIN
SERVICES
SERVICES compose primitives — INTEL + CHAT + COIN. Every service governed. Every scope discovered.
MUST: Maintain TRIAD integrity (CANON.md + VOCAB.md + README.md)
MUST: Treat SPEC as scope identity (`{SCOPE}` directory), not as a file
MUST: Every SERVICE scope include ROADMAP.md, COVERAGE.md, LEARNING.md, and `{SCOPE}.md` as governed content surfaces
MUST: Discover SERVICE scopes from filesystem only (no manual catalog)
MUST: Keep http:// and magic:// on the same namespace (transport differs, scope path matches)
MUST: CANON.md = axiom + universal constraints (no service names, no paths, no implementation)
MUST: README.md = how to run the CANON (nothing else)
MUST: {SCOPE}.md = SPEC — the interface (purpose, routes, projections, ecosystem)
MUST: SHOP.md = public projection file (per scope, filesystem-discoverable)
MUST: VAULT.md = private projection file (per scope, filesystem-discoverable)
MUST: Runtime implementation remains under ~/.canonic; this workspace is governance-first
MUST NOT: Hardcode service names in CANON constraints (law speaks universals)
MUST NOT: Define ungoverned terms outside VOCAB.md
MUST NOT: Treat `{SCOPE}.md` as SPEC identity
MUST NOT: Move architecture/lifecycle into README
MUST NOT: Leak private projections to public surfaces
MUST NOT: Maintain duplicate mapping tables outside generated manifest outputs
MUST NOT: Add runtime jargon to governance contracts
MUST: Ledger-consuming services declare source ledgers, scope filters, and closure gates
MUST: Learning governance remains live — closure claims require fresh DISCOVER → GENERATE → RELINK evidence
hadleylab-canonic
HADLEYLAB ships software. Every app, book, paper, deal, and patent is PROOF that MAGIC works. COIN = WORK. LEARNING = COMPUTE.
MUST: Every app, book, paper, deal, or patent is evidence of MAGIC MUST: All scopes inherit canonic-canonic/CANONIC.md governance MUST: All users governed under USERS/ via SERVICES/USER MUST: Cross-index INTEL across users (INTEL.md) MUST: Shared events propagate to ALL affected user dashboards MUST: Maintain governance workspace purity (.md files only) MUST: Ledger all COIN (validated work) through MAGIC 255 MUST: Compile all INTEL from governed sources MUST: Keep frontend/runtime implementation under ~/.canonic (hidden runtime) MUST: Surface governed TALK, Library, and SERVICES scopes (no orphan content) MUST: Derive nav labels from governed scope names (no hardcoded strings) MUST NOT: Publish without governance (CANON.md required) MUST NOT: Duplicate primitives — compose from INTEL, CHAT, COIN MUST NOT: Silo intelligence inside a single user when multiple are affected MUST NOT: Expose VAULT contents outside NDA scope MUST NOT: Store runtime artifacts in governance workspace
canonic-canonic
SPEC is governance. `canonic-canonic/` is the spec root.
MUST: Keep this repo governance-only (.md/.pdf) MUST: Publish workspace mapping in CANONIC.git (no hardcoded repo lists) MUST: Preserve three primary lanes: FOUNDATION, INDUSTRIES, MAGIC MUST NOT: Commit runtime artifacts here (runtime belongs in ~/.canonic/) MUST: Sell MAGIC tiers — the product, not the proof (proof is hadleylab-canonic) MUST NOT: Embed beta-test app URLs in platform page content