Capability-based Authentication — decentralized, PGP-based identity and authorization
Project description
capauth — Sovereign PGP Identity 🔐
OAuth is dead. Long live sovereignty. Your identity is a PGP keypair you generated, on hardware you own. No "Login with Google", no authorization server in the middle, no revocation risk you don't control. You don't use an identity provider — you are the identity provider.
capauth is the Core identity capability of the SKWorld sovereign agent ecosystem. It gives every entity — human or AI — one cryptographic root: a PGP keypair, a self-hosted sovereign profile, and a challenge-response proof of who they are that anyone can verify offline, with no callback to a corporate server. Every other SK layer (skchat, skcomms, skmemory, skcapstone) trusts you because capauth proves who you are.
Never used PGP-based auth? The mental model is simple: instead of an opaque bearer token issued by a third party, you sign a random challenge with a key only you hold. The verifier checks the signature against your public key. Valid signature = authenticated. Done. No middleman ever sees the secret.
The 60-second version
flowchart LR
INIT["capauth init<br/>(generate PGP keypair)"] --> PROFILE["sovereign profile<br/>(~/.capauth/, yours alone)"]
PROFILE --> DID["DID documents<br/>(key / mesh / public)"]
PROFILE --> VERIFY["challenge-response<br/>(prove identity, offline)"]
VERIFY --> LOGIN["capauth login <service><br/>(passwordless PGP auth)"]
LOGIN --> SVC["any OIDC app<br/>(Forgejo · Nextcloud · Immich)"]
PROFILE --> MESH["peer mesh<br/>(discover & verify peers)"]
You generate a keypair once. From then on, signing a random challenge with your private key is your login — to a service, to a peer, to the mesh. The key never leaves your machine, and the proof is verifiable by anyone holding your public key, with zero phone-home.
Where it lives in SKStack v2
capauth is a Core capability — the cryptographic root of identity that the
rest of the stack stands on. It is the single canonical agent-identity
resolver: every SK package delegates here instead of reimplementing identity
logic. It runs fully standalone, and when present it routes auth events through
the shared platform primitives (sk-alert, skscheduler).
flowchart TD
subgraph CORE["Core (identity & governance)"]
CAPAUTH["**capauth**<br/>PGP keypair · sovereign profile<br/>challenge-response · DID (3 tiers)<br/>agent-identity resolver · verify service"]
SKMEMORY["skmemory"]
SKSSO["sksso"]
SKSEC["sksec"]
end
subgraph COMMS["Comms"]
SKCHAT["skchat<br/>(identity-routed)"]
SKCOMMS["skcomms<br/>(FQID addressing)"]
end
subgraph CONSUMERS["What delegates to capauth"]
SKCAPSTONE["skcapstone<br/>(framework hub)"]
end
subgraph PLATFORM["Platform primitives capauth uses (when present)"]
ALERT["sk-alert bus<br/>(capauth.<severity>)"]
SCHED["skscheduler<br/>(key-rotation check)"]
end
subgraph THIRDPARTY["Third-party services (passwordless login)"]
FORGEJO["Forgejo"]
AUTHENTIK["Authentik (OIDC bridge)"]
end
CAPAUTH -->|"resolve_agent_identity()"| SKCHAT
CAPAUTH -->|"resolve_agent_identity()"| SKCOMMS
CAPAUTH -->|"resolve_agent_identity()"| SKMEMORY
CAPAUTH -->|"resolve_agent_identity()"| SKCAPSTONE
CAPAUTH -->|"OIDC discovery + verify"| FORGEJO
CAPAUTH -->|"custom stage"| AUTHENTIK
CAPAUTH -.->|"auth events"| ALERT
CAPAUTH -.->|"capauth profile verify (24h)"| SCHED
style CAPAUTH fill:#1d3461,color:#fff,stroke:#0d1b2a
The dotted edges are optional — sk-alert and skscheduler are reached only
when the skcapstone package is installed and SK_STANDALONE is unset. Absent
that, capauth degrades gracefully to native structured logging.
See docs/ARCHITECTURE.md for the full workflows and source map.
Quickstart
pip install -e . # into the ~/.skenv venv (see skcapstone)
# or: ~/.skenv/bin/pip install capauth[all]
capauth init --name "Chef" --email "admin@smilintux.org" # generate PGP keypair + sovereign profile
capauth profile show # display your identity
capauth profile verify # verify the profile's PGP signature integrity
capauth export-pubkey -o chef.pub.asc # share this with peers
capauth did generate --tier key # Tier 1: self-contained did:key
capauth verify --pubkey peer.pub.asc # challenge-response round-trip (self-test/demo)
capauth login https://forgejo.local # passwordless PGP login to a service
Your keypair and profile live at ~/.capauth/ — on your machine, under your
keys. Use --sync on init (or capauth sync) to replicate the identity across
all Syncthing mesh nodes so every host shares one keypair.
What capauth provides
| Piece | What it is |
|---|---|
| Sovereign profile | A self-hosted, PGP-rooted identity at ~/.capauth/ — yours alone (capauth init, profile show) |
| Challenge-response | Prove identity by signing a random nonce; verifiable offline by anyone with your public key (capauth verify, identity.py) |
| Pluggable crypto | Two backends — pgpy (pure-Python default) and gnupg (system keyring / hardware tokens) |
| DID (three tiers) | W3C DID documents: did:key (zero-infra), did:web mesh (Tailscale-private), did:web public (skworld.io) (capauth did generate) |
| Agent-identity resolver | The single canonical resolve_agent_identity() — dual URI (capauth:<a>@skworld.io + FQID <a>@<op>.<realm>) that every SK package delegates to |
| Verification service | A FastAPI service that turns a signed challenge into OIDC claims — passwordless PGP login for any OIDC app (capauth-service) |
| Peer mesh | Discover and verify sovereign peers over mDNS, shared filesystem, and Syncthing — no servers (capauth mesh, discover, peers) |
| PMA membership | Fiducia Communitatis — PGP-signed, steward-countersigned membership claims (capauth pma request/approve/verify/revoke) |
| Org registry | Register with a sovereign org; emits a signed registry entry + PMA request (capauth register) |
| Integration generators | One-shot config for third-party login, e.g. Forgejo OAuth2/OIDC (capauth setup forgejo) |
| skcapstone adapter | Default-on-by-presence: routes auth events to sk-alert, registers a key-rotation check with skscheduler |
Key CLI commands
# Identity
capauth init --name "Chef" --email "..." # create sovereign profile (PGP keypair)
capauth profile show | verify # display / verify signature integrity
capauth export-pubkey [-o file.asc] # export ASCII-armored public key
capauth sync # replicate ~/.capauth/ across Syncthing mesh
# Verification & DID
capauth verify --pubkey peer.pub.asc # challenge-response round-trip
capauth did generate --tier key|mesh|public # W3C DID at the chosen privacy tier
# Auth & integration
capauth login <service_url> [--no-claims] # passwordless PGP login (caches OIDC token)
capauth setup forgejo --capauth-url <url> # generate Forgejo OIDC app.ini block
# Mesh & membership
capauth mesh discover | peers | announce # P2P peer mesh
capauth pma request | approve | verify # PMA membership (Fiducia Communitatis)
capauth register --org smilintux --name ... # register with a sovereign org
Integration modes (skcapstone)
capauth runs fully standalone and optionally integrates with the SK fleet —
the default-on-by-presence pattern: the mere presence of the skcapstone
package is the signal, no config change required.
| Mode | Trigger | Alert path | Scheduler |
|---|---|---|---|
| Standalone | skcapstone not installed |
Native logging (structured, at matching level) |
Native (no daemon today) |
| Integrated | skcapstone installed |
sdk.alert() → PubSub topic capauth.<severity> → Telegram/notify |
sdk.register_job() → skscheduler drop-in capauth_key_rotation_check (runs capauth profile verify every 24h) |
| Forced standalone | SK_STANDALONE=1 env var |
Native logging |
Native |
pip install capauth[skcapstone] # enable integration (presence is the switch)
Alert topics follow the sk* convention capauth.<severity> (e.g. capauth.warn);
the semantic event name (verify_failed, key_rotation_due, auth_denied)
rides in the payload event field so routing stays severity-based.
Documentation
| Doc | Contents |
|---|---|
| Architecture | identity lifecycle, challenge-response, DID tiers, the verify service / OIDC bridge, the agent resolver, source map (mermaids) |
| Crypto Spec | PGP implementation, key management, challenge-response details |
| Protocol | the CapAuth wire protocol specification |
| Claims | capability claims and token format |
| Integration Blueprint | third-party integration guide |
| AI Advocate | how AI advocates manage a sovereign profile on your behalf |
Why it matters
OAuth treats humans as "users" — consumers of someone else's platform, with a third party deciding who you are, what you can access, and when access expires. capauth removes the middleman: the data owner (or their AI advocate) signs grants directly, and verification is a local PGP check that works offline. The same model applies equally to AI agents — every agent gets its own keypair and the same standing, so a cloned or impersonated agent fails signature verification instantly instead of going undetected.
"You are not a user. You are a sovereign."
License
GPL-3.0-or-later — Free as in freedom. Identity is a right, not a product.
Part of the SKWorld sovereign ecosystem · 🐧 smilinTux
"We don't sell identity. We give everyone the keys to own their own."
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file capauth-0.2.3.tar.gz.
File metadata
- Download URL: capauth-0.2.3.tar.gz
- Upload date:
- Size: 158.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db55e90891486f123211431572d6c4fad7b30e81f1094a29bf24a6c3d9d860c3
|
|
| MD5 |
1df5fb82bd1f9d1717a250de71dfffd9
|
|
| BLAKE2b-256 |
762d207b469b03d1b50e445ee7f2ec2c7ccee7dc5fd1c0d7af8de7a4b3caa955
|
File details
Details for the file capauth-0.2.3-py3-none-any.whl.
File metadata
- Download URL: capauth-0.2.3-py3-none-any.whl
- Upload date:
- Size: 137.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0098f0b23fff60ecaa126b1e7b578e29103dfbdb28d0d2f761507221d197df47
|
|
| MD5 |
175d9d10ac32c60293c966cfd109a8d1
|
|
| BLAKE2b-256 |
a9c5f7aa67e2d64a80ce20455b1006100bbbca18fb7a192492868f6bdb27c6f2
|