Metadata-Version: 2.4
Name: capauth
Version: 0.2.3
Summary: Capability-based Authentication — decentralized, PGP-based identity and authorization
Author-email: smilinTux <admin@smilintux.org>
License: GPL-3.0-or-later
Project-URL: Homepage, https://capauth.io
Project-URL: Documentation, https://capauth.io
Project-URL: Repository, https://github.com/smilinTux/capauth
Project-URL: Issues, https://github.com/smilinTux/capauth/issues
Project-URL: Changelog, https://github.com/smilinTux/capauth/releases
Keywords: authentication,pgp,decentralized,identity,capability
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Requires-Dist: pydantic>=2.0
Requires-Dist: PGPy>=0.6
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0
Requires-Dist: httpx>=0.25
Provides-Extra: skcapstone
Requires-Dist: skcapstone>=0.6.8; extra == "skcapstone"
Provides-Extra: gnupg
Requires-Dist: python-gnupg>=0.5; extra == "gnupg"
Provides-Extra: service
Requires-Dist: fastapi>=0.110; extra == "service"
Requires-Dist: uvicorn[standard]>=0.27; extra == "service"
Requires-Dist: PyJWT>=2.8; extra == "service"
Requires-Dist: python-gnupg>=0.5; extra == "service"
Requires-Dist: httpx>=0.25; extra == "service"
Requires-Dist: segno>=1.6; extra == "service"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: httpx>=0.25; extra == "dev"
Requires-Dist: fastapi>=0.110; extra == "dev"
Requires-Dist: python-gnupg>=0.5; extra == "dev"
Requires-Dist: black>=24.0; extra == "dev"
Requires-Dist: ruff>=0.3; extra == "dev"
Requires-Dist: zeroconf>=0.38; extra == "dev"
Provides-Extra: all
Requires-Dist: capauth[dev,gnupg,service]; extra == "all"
Dynamic: license-file

# 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](https://skworld.io)
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

```mermaid
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 &lt;service&gt;<br/>(passwordless PGP auth)"]
    LOGIN --> SVC["any OIDC app<br/>(Forgejo · Nextcloud · Immich)"]
    PROFILE --> MESH["peer mesh<br/>(discover &amp; 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`).

```mermaid
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.&lt;severity&gt;)"]
      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](docs/ARCHITECTURE.md)** for the full workflows and
source map.

## Quickstart

```bash
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

```bash
# 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 |

```bash
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](docs/ARCHITECTURE.md)** | identity lifecycle, challenge-response, DID tiers, the verify service / OIDC bridge, the agent resolver, source map (mermaids) |
| **[Crypto Spec](docs/CRYPTO_SPEC.md)** | PGP implementation, key management, challenge-response details |
| **[Protocol](docs/PROTOCOL.md)** | the CapAuth wire protocol specification |
| **[Claims](docs/CLAIMS.md)** | capability claims and token format |
| **[Integration Blueprint](docs/INTEGRATION_BLUEPRINT.md)** | third-party integration guide |
| **[AI Advocate](AI-ADVOCATE.md)** | 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](https://skworld.io)** sovereign ecosystem · 🐧 smilinTux

*"We don't sell identity. We give everyone the keys to own their own."*
