capauth 0.3.13__tar.gz → 0.3.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- capauth-0.3.14/AGENTS.md +99 -0
- {capauth-0.3.13 → capauth-0.3.14}/CHANGELOG.md +11 -0
- {capauth-0.3.13 → capauth-0.3.14}/Dockerfile.authentik-capauth +22 -5
- {capauth-0.3.13/src/capauth.egg-info → capauth-0.3.14}/PKG-INFO +4 -4
- {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_STRATEGY_DECISION.md +188 -43
- {capauth-0.3.13 → capauth-0.3.14}/pyproject.toml +3 -3
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integration.py +3 -3
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/provider.py +87 -16
- {capauth-0.3.13 → capauth-0.3.14/src/capauth.egg-info}/PKG-INFO +4 -4
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/SOURCES.txt +1 -2
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/requires.txt +3 -3
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/scm_file_list.json +1 -2
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_integration.py +14 -3
- capauth-0.3.14/tests/test_oidc_login_passphrase_dialog.py +38 -0
- {capauth-0.3.13 → capauth-0.3.14}/urllib.error +1 -1
- capauth-0.3.13/.cursorrules +0 -15
- capauth-0.3.13/AGENTS.md +0 -24
- capauth-0.3.13/CLAUDE.md +0 -144
- {capauth-0.3.13 → capauth-0.3.14}/.dockerignore +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/ci.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/docs-check.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/image.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/nextcloud-appstore.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/publish.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/pytest.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/secret-scan.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.gitignore +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.gitleaks-baseline.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/.gitleaks.toml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/AI-ADVOCATE.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/ARCHITECTURE.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/CODE_OF_CONDUCT.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/CONTRIBUTING.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/Dockerfile +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/LICENSE +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/MANIFEST.in +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/MISSION.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/README.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/SECURITY.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/SKILL.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/SOP.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/authentik-custom/capauth_migrate.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/authentik-custom/imghdr.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/authentik-custom/user_settings.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/bin/cli.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/.gitignore +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/README.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/RELEASING.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/background.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/autofill.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/cross_origin_signing.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/detector.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/provider.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/provider_bridge.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon.svg +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon128.png +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon16.png +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon48.png +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/bunker-e2e.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/keyqr.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/keyvault.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/openpgp.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/signer-backends.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/manifest.firefox.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/manifest.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/native-host/capauth_signer.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/native-host/com.capauth.signer.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/native-host/install.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/options/options.html +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/options/options.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/package-lock.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/package.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/popup/popup.css +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/popup/popup.html +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/popup/popup.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/scripts/build.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/scripts/generate-icons.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/AuthenticatorSelectionStage.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/CapAuthStage.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/QRDisplayStage.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/SignatureVerificationStage.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/StagePipeline.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/submission/STORE_LISTING.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/submission/privacy-policy.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/fixtures/test_key.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/background.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/bunker_e2e.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/detector.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/keyqr.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/keyvault.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/openpgp.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/provider_api.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/provider_tierb.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/remote_bunker.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/signer_backends.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/browser-extension/vitest.config.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/.env.example +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/deploy.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/docker-compose.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/systemd/capauth-backup.service +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/systemd/capauth-backup.timer +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/forgejo-capauth/.env.example +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/forgejo-capauth/docker-compose.yml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/deploy/forgejo-capauth/preflight.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/AIRGAPPED_SIGNING_WORKSTATION.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/ARCHITECTURE.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_CUSTOM_STAGE.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_DEPLOYMENT_SKSSO.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_FORGEJO_DEPLOYMENT.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/CAPAUTH-WEBAUTHN-05-QUALIFICATION.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/CAPAUTH_BUNKER_REMOTE_SIGNER.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/CAPAUTH_OIDC_IDP.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/CLAIMS.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/COLD_MACHINE_BOOTSTRAP_AND_DR.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/CRYPTO_SPEC.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/DELEGATED_CAPABILITIES.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/DOWNSTREAM_DURABLE_BACKENDS.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/ENTERPRISE_MANAGED_KEYS.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/HUMAN_IDENTITY_SETUP_AND_ROTATION.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/IDENTITY_ESTATE.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/INTEGRATION_BLUEPRINT.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/M0-capauth-api-v1.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/M0-capauth-importer-inventory.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/PASSPHRASE_ROTATION.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/PQC_CAPAUTH_REVISIT.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/PQC_ROOT_MIGRATION.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/PROTOCOL.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/ROOT_ROTATION_CEREMONY.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/SIGN_CHALLENGE.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/SKDASHBOARD_CONTROL_PLANE_POLICY.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/TRUST_GRAPH_COORD_PROJECTION.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/ZERO_KNOWLEDGE_PROFILE.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/audits/BLAST-RADIUS-CAPAUTH-01.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/audits/BLAST-RADIUS-CAPAUTH-01.sha256 +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/authentik-capauth.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/deploy-plan/capauth-bulletproof-deploy.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/evidence/capauth/SKL-CAPAUTH-SIGNER-P3P-MUTATION-ENVELOPE-2026-08-25.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/docs/evidence/capauth/SKL-CAPAUTH-SIGNER-P3P-ROSTER-2026-08-25.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/index.d.ts +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/index.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/openclaw-plugin.archived-2026-04-23/package.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/openclaw-plugin.archived-2026-04-23/src/index.ts +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/openclaw-plugin.archived-2026-04-23/src/openclaw.plugin.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/package.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/app.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/icons/icon-192.png +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/icons/icon-512.png +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/index.html +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/bunker-e2e.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/bunker-signer.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/canonical.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/keyqr.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/keyvault.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/manifest.webmanifest +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/sw.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/vendor/openpgp.min.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/phone-signer/vendor/qrcode-generator.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/scripts/build_authentik_capauth_image.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/scripts/capauth-backup.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/scripts/capauth-restore.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/scripts/gitleaks-scope.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/scripts/migrate_canonical_subjects.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/scripts/pqc_ceremony_dryrun.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/scripts/provision_agent_profiles.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/setup.cfg +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/skill.yaml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/agent_identity.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/apps.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/api.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/blueprints/capauth-pgp-login.yaml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/claims_mapper.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/nonce_store.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/stage.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/urls.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/verifier.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authz.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/cli.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/control_plane.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/control_plane_authorizer.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/control_plane_session.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/base.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/gnupg_backend.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/pgpy_backend.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/sequoia_backend.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/skpgp_backend.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/custody.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/delegated.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/did.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/base.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/file_discovery.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/mdns.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/syncthing.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/estate.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/exceptions.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/identity.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/identity_class.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/auth_flow.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/cli.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/config.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/forgejo_api.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/oidc_provider.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_auth_flow.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_cli.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_config.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_forgejo_api.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_oidc_provider.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/.gitignore +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/.nextcloudignore +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/CSR-PR.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/INFO-XML-CHANGES.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/PUBLISHING.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/README.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/appinfo/info.xml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/appinfo/routes.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/build-release.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/certificates/.gitignore +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/certificates/capauth.crt +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/certificates/capauth.csr +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/composer.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/css/login.css +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/js/login.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/krankerl.toml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/AlternativeLogin/CapAuthLogin.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/AppInfo/Application.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/BackgroundJob/PruneExpiredNonces.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Controller/LoginController.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Controller/TokenController.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Db/KeyRegistry.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Exception/CapAuthUnauthorizedException.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Middleware/PgpVerificationMiddleware.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Migration/Version000300Date20260301000000.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Provider/CapAuthProvider.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/ChallengeService.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/GroupSyncService.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/UserProvisioningService.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/VerifierService.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/User/Backend.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/phpunit.xml +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/screenshots/README.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/screenshots/login.png +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/templates/login.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/bootstrap.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/integration/FullAuthFlowTest.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/oidc/oidc_e2e_login_test.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Controller/LoginControllerTest.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Db/KeyRegistryTest.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Provider/CapAuthProviderTest.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Service/ChallengeServiceTest.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Service/VerifierServiceTest.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/User/BackendTest.php +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/key_transparency.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/login.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/manifest.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/mesh.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/migrations/0001_initial.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/migrations/0002_widen_fingerprint_to_64.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/migrations/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/models.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/canonicalize.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/kernel.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/operator_session.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/proof.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/records.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/store.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/window.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pma.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_confidentiality.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_identity.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_root_identity.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_tokens.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/profile.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/provisioning.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/registry.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/rotation.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/seal.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/app.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/bunker.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/bunker_e2e.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/keystore.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/clients.example.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/clients.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/passkey.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/signing_key.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/static/bunker/lib/bunker-e2e.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/static/bunker/lib/keyvault.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/static/bunker/vendor/openpgp.min.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/store.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/push.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/server.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/sign_challenge.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/subject.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/sync.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/testing.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/tokens.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/trust/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/trust/calibration.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth/trust/graph.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/dependency_links.txt +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/entry_points.txt +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/top_level.txt +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/.gitignore +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/package-lock.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/package.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/src/CapAuthStage.test.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/src/CapAuthStage.vue +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/src/index.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/vite.config.js +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/__init__.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/conftest.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/fixtures/bunker_e2e_v1_vector.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/fixtures/canonical_nonce_v2_vector.json +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_agent_identity.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_agentrun_capabilities.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_audience_mint_helper.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_audience_tokens.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_audience_ttl_seconds.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_authz.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_authz_legacy_grace.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_authz_signature_gate.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_backup_fallback.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_backup_restore.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_bunker.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_bunker_e2e.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_canonicalize.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_capauth_service_deploy.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_change_capabilities.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_claims_mapper.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane_authorizer.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane_capabilities.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane_session.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_crypto.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_custody.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_delegated_capabilities.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_device_key_proof.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_did_capability_relationships.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_dockerfile_version.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_enrollment_proof_helper.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_estate.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_fingerprint_v6.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_forgejo_preflight.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_home_resolution.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_identity.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_identity_class.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_identity_ttl.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_installed_bunker_assets.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_key_revocation_expiry.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_key_transparency.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_login.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_manifest.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_mesh.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_models_pqc_q0.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_nextcloud_app.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_no_subapp_dependency.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_nonce_store.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_durable_store.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_hardening.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_idp.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_idp_e2e.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_refresh_family.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_operator_session.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pairing.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pairing_base_dir_env.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_passkey.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_passkey_enrollment_ux.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pma.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_confidentiality.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_identity.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_root_integration.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_t3_gate.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_tokens.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_profile.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_provisioning.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_push.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_py313_compat.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_qr_login.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_real_pgp_e2e.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_register_cli.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_registry.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_rotation.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_seal.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_sequoia_backend.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_service.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_service_authz_decide.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_service_v6_fingerprint.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_sign_challenge.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_skpgp_backend.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_subject.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_sync.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_syncthing_discovery.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_testing_helper.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_token_gc.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_token_store_flag.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_tokens.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_trust_calibration.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_trust_graph.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_trust_graph_coord_audit.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_verifier.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_version_honesty.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tests/test_zk_profile.py +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/tools/build-sq.sh +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/web/README.md +0 -0
- {capauth-0.3.13 → capauth-0.3.14}/web/stages/capauth/CapAuthStage.ts +0 -0
capauth-0.3.14/AGENTS.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# AGENTS.md (capauth)
|
|
2
|
+
|
|
3
|
+
CapAuth: PGP-based sovereign identity and authentication for the SK stack (Python library, `capauth`
|
|
4
|
+
CLI and FastAPI verification service). Overview: [README.md](./README.md). Operations:
|
|
5
|
+
[SOP.md](./SOP.md). Architecture: [ARCHITECTURE.md](./ARCHITECTURE.md). This file follows
|
|
6
|
+
[AGENT_INSTRUCTIONS_STANDARD](https://github.com/smilinTux/sk-standards/blob/main/standards/AGENT_INSTRUCTIONS_STANDARD.md).
|
|
7
|
+
There is no `CLAUDE.md` or `.cursorrules`: every agent reads this file.
|
|
8
|
+
|
|
9
|
+
## Source of truth and invariants
|
|
10
|
+
|
|
11
|
+
- **CapAuth owns the one canonical agent identity resolver**, `resolve_agent_identity` in
|
|
12
|
+
`src/capauth/agent_identity.py` (re-exported from `capauth`). skchat, skcomms, skmemory and
|
|
13
|
+
skcapstone delegate to it; never reimplement identity logic elsewhere. It returns a dual URI:
|
|
14
|
+
`capauth_uri` (`capauth:<agent>@<domain>`, the wire identity, always derivable) and `fqid`
|
|
15
|
+
(`<agent>@<operator>.<realm>`, read from `~/.skcapstone/cluster.json`).
|
|
16
|
+
- **Operator vs agents:** the shared `~/.skcapstone/identity/identity.json` holds the operator
|
|
17
|
+
identity (`role: operator`); each agent's wire identity resolves per agent. No identity carries an
|
|
18
|
+
`@capauth.local` placeholder (`skcapstone doctor` `identity:*` checks).
|
|
19
|
+
- **DID documents, three tiers** (`src/capauth/did.py`): `did:key` (self-contained), mesh-private
|
|
20
|
+
`did:web`, and public `did:web` (minimal: key, name, org). `from_profile()` reads only
|
|
21
|
+
`public_key_armor`; a private key is never touched; no tailnet IPs and no `memory`, `journal` or
|
|
22
|
+
detailed `soul` fields appear in any document; the public tier respects
|
|
23
|
+
`publish_to_skworld: false` in `~/.capauth/config.yaml`.
|
|
24
|
+
- **Crypto goes through a backend**, never hand-rolled primitives: `src/capauth/crypto/`
|
|
25
|
+
(`pgpy_backend.py`, `gnupg_backend.py`, `sequoia_backend.py`). Only `sequoia_backend.py` (the `sq`
|
|
26
|
+
CLI) can sign post-quantum; GnuPG is signing-disqualified for PQC. Hybrid combiners are HKDF over
|
|
27
|
+
both shared secrets, never XOR and never pure PQ.
|
|
28
|
+
- **The live root identity is still classical.** PQC root migration is additive-first and
|
|
29
|
+
reversible, gated on a root-rotation ceremony (epic `PQC-MIGRATION`). Do not claim a PQC root.
|
|
30
|
+
Per-surface status: [docs/CRYPTO_SPEC.md](./docs/CRYPTO_SPEC.md).
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
CI: `.github/workflows/ci.yml` (test on 3.10 to 3.12, lint, build), `pytest.yml`, `secret-scan.yml`,
|
|
35
|
+
`docs-check.yml` (sk-standards gate, tiers 1 to 3).
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install -e ".[dev,service]"
|
|
39
|
+
python -m pytest tests/ -v --tb=short --cov=capauth # CI test
|
|
40
|
+
pip install "ruff==0.15.4"
|
|
41
|
+
ruff format --check src/ tests/ # CI lint, step 1
|
|
42
|
+
ruff check src/ # CI lint, step 2
|
|
43
|
+
python -m build && twine check dist/* # CI build
|
|
44
|
+
scripts/gitleaks-scope.sh full # CI secret scan
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
On 3.11+ CI also installs `skcapstone` and `skcoord` from git with `--no-deps` so
|
|
48
|
+
`tests/test_integration.py` runs instead of skipping; skcapstone is an optional backbone, never a
|
|
49
|
+
dependency (skcapstone depends on capauth, not the other way round). Ruff config is in
|
|
50
|
+
`pyproject.toml` (line length 99, rules `E,F,I,N,W`, `E501` ignored).
|
|
51
|
+
|
|
52
|
+
## Start here
|
|
53
|
+
|
|
54
|
+
1. `src/capauth/cli.py`: every `capauth` command.
|
|
55
|
+
2. `src/capauth/agent_identity.py`: the unified identity resolver.
|
|
56
|
+
3. `src/capauth/identity.py` and `src/capauth/did.py`: challenge-response and DID generation.
|
|
57
|
+
4. `src/capauth/crypto/`: the crypto backends.
|
|
58
|
+
5. `src/capauth/service/`: the FastAPI service (`app.py`, `server.py`, `keystore.py`).
|
|
59
|
+
|
|
60
|
+
## Rules
|
|
61
|
+
|
|
62
|
+
- **Writing style:** no em dashes (U+2014) and no en dashes (U+2013) anywhere: code, comments,
|
|
63
|
+
docs, commits, PR bodies. Use commas, parentheses, colons or a new sentence. Hyphens are fine.
|
|
64
|
+
- **Branch and commit:** never commit to `main`. Branch, commit as soon as a fast check passes and
|
|
65
|
+
before the full suite, then open a PR. Add an `## [Unreleased]` entry to
|
|
66
|
+
[CHANGELOG.md](./CHANGELOG.md) for any user-visible change.
|
|
67
|
+
- **Attribution:** a `Co-Authored-By` trailer names the agent that actually did the work, or is
|
|
68
|
+
left out. Never one you cannot evidence.
|
|
69
|
+
- **Code style:** Python 3.11+ for new code (the package still supports 3.10), type hints, pydantic
|
|
70
|
+
models, Google-style docstrings, at most 500 lines per file. Tests in `tests/` cover happy path,
|
|
71
|
+
edge case and failure.
|
|
72
|
+
- **Coordination:** run `skcapstone coord briefing` at the start of a session; claim work with
|
|
73
|
+
`skcapstone coord claim <id> --agent <you>`. SK packages install into `~/.skenv/`.
|
|
74
|
+
- **Generated files:** none checked in; build artefacts come from `python -m build`.
|
|
75
|
+
|
|
76
|
+
## Privacy
|
|
77
|
+
|
|
78
|
+
This repo is public. Never put host names, LAN or tailnet IPs, estate names, personal names or data,
|
|
79
|
+
real key fingerprints, private keys or credentials in code, docs, tests, fixtures or commits.
|
|
80
|
+
Enforced by `secret-scan.yml` (`scripts/gitleaks-scope.sh`) and, for
|
|
81
|
+
DID output, by the invariants in `did.py`; the rest is on review.
|
|
82
|
+
|
|
83
|
+
## Hazards
|
|
84
|
+
|
|
85
|
+
- **Environment-gated tests:** `pytest.yml` ignores `tests/test_integration.py` and deselects a few
|
|
86
|
+
Sequoia and QR-login tests that need tools CI lacks. A green `pytest.yml` is not the full suite;
|
|
87
|
+
`ci.yml` is.
|
|
88
|
+
- **No `capauth did` CLI group:** the identity card is a library and MCP surface (see SOP section 7).
|
|
89
|
+
- **Stray tracked files:** `ruff-0.15.4-*.whl` and `urllib.error` at the repo root are accidental
|
|
90
|
+
commits, not inputs; do not depend on them or add more like them.
|
|
91
|
+
|
|
92
|
+
## See also
|
|
93
|
+
|
|
94
|
+
- [skcapstone](https://github.com/smilinTux/skcapstone): agent framework, coordination board,
|
|
95
|
+
`skcapstone doctor`.
|
|
96
|
+
- [skcomms](https://github.com/smilinTux/skcomms) and [skchat](https://github.com/smilinTux/skchat):
|
|
97
|
+
consumers of the identity resolver.
|
|
98
|
+
- [sk-standards](https://github.com/smilinTux/sk-standards): `CRYPTOGRAPHY_STANDARD`,
|
|
99
|
+
`SK_REPO_DOC_STANDARD`, `AGENT_INSTRUCTIONS_STANDARD`.
|
|
@@ -6,6 +6,16 @@ All notable changes to `capauth` are documented here. The format is based on
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
- Agent instructions live in one file, `AGENTS.md`, reshaped to the sk-standards
|
|
10
|
+
AGENT_INSTRUCTIONS_STANDARD. `CLAUDE.md` and `.cursorrules` are removed (Claude Code reads
|
|
11
|
+
`AGENTS.md` natively and skips it when a `CLAUDE.md` sits next to it).
|
|
12
|
+
|
|
13
|
+
- OIDC login asks for the vault passphrase in a masked in-page dialog instead of
|
|
14
|
+
a browser `prompt()`, which showed the passphrase as it was typed.
|
|
15
|
+
|
|
16
|
+
- Service discovery no longer invents a nonexistent CapAuth PID file. Without
|
|
17
|
+
an explicit daemon-owned PID path, health remains unknown.
|
|
18
|
+
|
|
9
19
|
- Release tags (`v*`) now also publish the service image
|
|
10
20
|
`ghcr.io/smilintux/capauth:<version>` (`.github/workflows/image.yml`): the
|
|
11
21
|
tag must be on main, a published version is never overwritten, the image is
|
|
@@ -573,6 +583,7 @@ All notable changes to `capauth` are documented here. The format is based on
|
|
|
573
583
|
|
|
574
584
|
### Security
|
|
575
585
|
|
|
586
|
+
- Raised `python-multipart` to `>=0.0.31`, `PyJWT` to `>=2.15.0` and `zeroconf` to `>=0.149.16` to clear the 2026-11-13 dependency sweep findings.
|
|
576
587
|
- **Revoked / expired signing-key rejection**: the `pgpy` and `gnupg` verify
|
|
577
588
|
paths now reject a signing key that carries a revocation signature or is expired
|
|
578
589
|
**before** the signature check (`KeyRevokedError` / `KeyExpiredError`), closing
|
|
@@ -4,16 +4,26 @@
|
|
|
4
4
|
#
|
|
5
5
|
# Build:
|
|
6
6
|
# docker build -f Dockerfile.authentik-capauth \
|
|
7
|
-
# -t
|
|
8
|
-
# -t
|
|
7
|
+
# -t skgit.skstack01.douno.it/skadmin/authentik-capauth:2025.12.6 \
|
|
8
|
+
# -t skgit.skstack01.douno.it/skadmin/authentik-capauth:latest .
|
|
9
9
|
#
|
|
10
10
|
# Push:
|
|
11
|
-
# docker push
|
|
12
|
-
# docker push
|
|
11
|
+
# docker push skgit.skstack01.douno.it/skadmin/authentik-capauth:2025.12.6
|
|
12
|
+
# docker push skgit.skstack01.douno.it/skadmin/authentik-capauth:latest
|
|
13
13
|
#
|
|
14
14
|
# AK_VERSION tracks the latest STABLE Authentik release (override with --build-arg).
|
|
15
|
+
#
|
|
16
|
+
# 2026-10-23 (Chef decision, tactical patch): pinned to 2025.12.6, the latest
|
|
17
|
+
# 2025.12.x patch, same major line as nor prod's running 2025.12.3. This is the
|
|
18
|
+
# SAME-LINE security patch (fixes GHSA-xp7f-xjjx-gwm8 Critical SourceStage bypass
|
|
19
|
+
# and GHSA-c3m2-jqmq-pvp3 SAML XML signature wrapping), not the full 2026.8.5
|
|
20
|
+
# migration. The 2025.12.x line does not receive the later privilege-escalation
|
|
21
|
+
# (GHSA-h6c5-mpvq-j4jc) or SAML-DoS (GHSA-cxwx-9x59-28qm) backports -- those land
|
|
22
|
+
# only with the full upgrade (see docs/AUTHENTIK_STRATEGY_DECISION.md, option b,
|
|
23
|
+
# decision 2026-10-23: retire this fork for CAPAUTH_ENABLED on stock Authentik as
|
|
24
|
+
# part of that upgrade).
|
|
15
25
|
# ──────────────────────────────────────────────────────────────────────
|
|
16
|
-
ARG AK_VERSION=
|
|
26
|
+
ARG AK_VERSION=2025.12.6
|
|
17
27
|
|
|
18
28
|
# ── Stage 1: Rebuild Authentik frontend with ak-stage-capauth ────────
|
|
19
29
|
FROM node:24-bookworm AS web-builder
|
|
@@ -60,6 +70,13 @@ USER root
|
|
|
60
70
|
# instead of hardcoding it — otherwise capauth lands on the wrong path and Django can't import
|
|
61
71
|
# it (ModuleNotFoundError: capauth, live-proven on .13 against 2026.5.3).
|
|
62
72
|
COPY . /app/capauth
|
|
73
|
+
# capauth's pyproject.toml uses setuptools_scm (dynamic version from git tags),
|
|
74
|
+
# but .dockerignore excludes .git from the build context, so `pip install
|
|
75
|
+
# /app/capauth` cannot infer a version and fails with "setuptools-scm was
|
|
76
|
+
# unable to detect version" (hit rebuilding this image 2026-10-23, unrelated
|
|
77
|
+
# to the AK_VERSION bump -- would fail the same way at any Authentik version
|
|
78
|
+
# until this is set). Pin it explicitly to the latest released tag.
|
|
79
|
+
ENV SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CAPAUTH=0.3.13
|
|
63
80
|
RUN VENV_SP="$(ls -d /ak-root/.venv/lib/python3.*/site-packages | head -1)" && \
|
|
64
81
|
echo "Installing capauth into $VENV_SP" && \
|
|
65
82
|
pip install --no-cache-dir --no-deps --target "$VENV_SP" /app/capauth && \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: capauth
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.14
|
|
4
4
|
Summary: Capability-based Authentication — decentralized, PGP-based identity and authorization
|
|
5
5
|
Author-email: smilinTux <admin@smilintux.org>
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -37,8 +37,8 @@ Requires-Dist: python-gnupg>=0.5; extra == "gnupg"
|
|
|
37
37
|
Provides-Extra: service
|
|
38
38
|
Requires-Dist: fastapi>=0.110; extra == "service"
|
|
39
39
|
Requires-Dist: uvicorn[standard]>=0.27; extra == "service"
|
|
40
|
-
Requires-Dist: python-multipart>=0.0.
|
|
41
|
-
Requires-Dist: PyJWT>=2.
|
|
40
|
+
Requires-Dist: python-multipart>=0.0.31; extra == "service"
|
|
41
|
+
Requires-Dist: PyJWT>=2.15.0; extra == "service"
|
|
42
42
|
Requires-Dist: python-gnupg>=0.5; extra == "service"
|
|
43
43
|
Requires-Dist: httpx>=0.25; extra == "service"
|
|
44
44
|
Requires-Dist: segno>=1.6; extra == "service"
|
|
@@ -53,7 +53,7 @@ Requires-Dist: fastapi>=0.110; extra == "dev"
|
|
|
53
53
|
Requires-Dist: python-gnupg>=0.5; extra == "dev"
|
|
54
54
|
Requires-Dist: black>=24.0; extra == "dev"
|
|
55
55
|
Requires-Dist: ruff>=0.3; extra == "dev"
|
|
56
|
-
Requires-Dist: zeroconf>=0.
|
|
56
|
+
Requires-Dist: zeroconf>=0.149.16; extra == "dev"
|
|
57
57
|
Requires-Dist: webauthn>=2.0; extra == "dev"
|
|
58
58
|
Requires-Dist: soft-webauthn>=0.1; extra == "dev"
|
|
59
59
|
Requires-Dist: pywebpush>=1.14; extra == "dev"
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
# Decision Document: Long-Term Strategy for the CapAuth ↔ Authentik Integration
|
|
2
2
|
|
|
3
|
-
**Status:**
|
|
4
|
-
**
|
|
5
|
-
**
|
|
3
|
+
**Status:** DECIDED. Chef chose CapAuth as an OAuth Source on STOCK Authentik,
|
|
4
|
+
retiring the custom fork. By this document's own lettering that is **Option C2 /
|
|
5
|
+
Track 2** (section 4 Option C, sub-flavor C2; section 5 Track 2). It is NOT
|
|
6
|
+
section 4 "Option B", which means keeping the custom image fork.
|
|
7
|
+
Chef's original words, relayed through the coordinator on 2026-10-23 as part of
|
|
8
|
+
the full Authentik 2026.8.5 upgrade: "patch now, and b for capauth." (Wording as
|
|
9
|
+
recorded in the original version of this PR; the repo holds no other record of it.)
|
|
10
|
+
Clarification 2026-11-07: Chef confirmed that "b for capauth" meant CapAuth as an
|
|
11
|
+
OAuth Source on stock Authentik (this document's C2 / Track 2), not keeping the
|
|
12
|
+
fork. It does not refer to this document's section 4 Option B.
|
|
13
|
+
Scope: this applies to the full 2026.8.5 migration, not the 2026-10-23 tactical
|
|
14
|
+
same-line security patch (nor to 2025.12.6, NAM to 2026.2.7), which keeps both
|
|
15
|
+
images on their current major line and does not touch the fork or the Source
|
|
16
|
+
integration. See "2026-10-23 cutover plan" at the end of this document.
|
|
17
|
+
**Date:** 2026-06-22 (proposed) / 2026-10-23 (decided)
|
|
18
|
+
**Author:** Opus (research + recommendation); decision recorded by Lumina per Chef/coordinator, corrected 2026-11-07 after Chef's clarification
|
|
6
19
|
**Scope:** How to maintain the CapAuth PGP passwordless login *inside* Authentik
|
|
7
|
-
long-term
|
|
20
|
+
long-term - upstream PR, fork/custom image, redistributable package, or drop
|
|
8
21
|
Authentik in favor of native per-app plugins.
|
|
9
22
|
|
|
10
23
|
> TL;DR recommendation: **Stop investing in the forked custom image as the
|
|
11
24
|
> primary path. Adopt a two-track strategy: (1) make native per-app CapAuth
|
|
12
25
|
> plugins the default sovereign login (Nextcloud is already done and works in a
|
|
13
26
|
> real browser); (2) keep Authentik integration alive in a *backend-only,
|
|
14
|
-
> non-web-patching* form
|
|
15
|
-
> NO web-bundle rebuild
|
|
27
|
+
> non-web-patching* form - a custom Django app layered on the stock image with
|
|
28
|
+
> NO web-bundle rebuild - and use Authentik's *existing* WebAuthn/passkey or an
|
|
16
29
|
> OIDC-source bridge for the browser UI rather than shipping our own Lit
|
|
17
30
|
> component.** Only pursue an upstream PR if we first reframe CapAuth as a
|
|
18
31
|
> *Source* (external IdP) rather than a built-in *Stage*. See §5.
|
|
@@ -42,7 +55,7 @@ current), which:
|
|
|
42
55
|
3. Registers the Django app by dropping `/data/user_settings.py` that puts
|
|
43
56
|
`capauth` into `TENANT_APPS`, and bakes a blueprint creating the stage + flow.
|
|
44
57
|
|
|
45
|
-
### 1.2 Why it is fragile (the cost of forking
|
|
58
|
+
### 1.2 Why it is fragile (the cost of forking - observed, not theoretical)
|
|
46
59
|
|
|
47
60
|
Every one of these has already bitten us on `.13`:
|
|
48
61
|
|
|
@@ -51,12 +64,12 @@ Every one of these has already bitten us on `.13`:
|
|
|
51
64
|
registry are *internal* files. We edit Authentik's own source to register a
|
|
52
65
|
component.
|
|
53
66
|
- **The from-source web build is currently broken and shipped DISABLED.** `npm
|
|
54
|
-
run build` hits an esbuild code-splitting bug
|
|
67
|
+
run build` hits an esbuild code-splitting bug - a shared chunk defines Lit's
|
|
55
68
|
`createRef` but doesn't re-export it across the chunk boundary → runtime SPA
|
|
56
69
|
throws `does not provide an export named 'createRef'` → blank spinner, SPA
|
|
57
70
|
never boots. Identical under `npm ci` *and* `npm install`, so it is the
|
|
58
|
-
from-source build itself, not version drift. **Net effect: cap9
|
|
59
|
-
stock frontend, so the `ak-stage-capauth` component is ABSENT
|
|
71
|
+
from-source build itself, not version drift. **Net effect: cap9-cap12 ship the
|
|
72
|
+
stock frontend, so the `ak-stage-capauth` component is ABSENT - the PGP login
|
|
60
73
|
form does not render in a browser.** PGP login is only proven via the
|
|
61
74
|
flow-executor API. (Our own blueprint comment says: "For in-browser PGP today,
|
|
62
75
|
use the native nextcloud `capauth` plugin instead.")
|
|
@@ -95,7 +108,7 @@ maintainer/founder **BeryJu** responded directly (verified via GitHub API):
|
|
|
95
108
|
This is the governing position. It tells us three things:
|
|
96
109
|
|
|
97
110
|
1. **Custom Django apps are not a supported public extension path.** They "work"
|
|
98
|
-
only because Django + `user_settings.py` lets you bolt one on
|
|
111
|
+
only because Django + `user_settings.py` lets you bolt one on - but the core
|
|
99
112
|
would need changes for clean dynamic hooking, and those changes don't exist.
|
|
100
113
|
Our `TENANT_APPS` injection is a **hack**, not a sanctioned mechanism.
|
|
101
114
|
2. **The sanctioned answers are: merge upstream, or use the API** (i.e. integrate
|
|
@@ -113,29 +126,29 @@ the docs (no plugin/extension API in
|
|
|
113
126
|
[Contributing](https://docs.goauthentik.io/developer-docs/contributing/) or the
|
|
114
127
|
[developer docs](https://docs.goauthentik.io/developer-docs/)) and by the
|
|
115
128
|
frontend architecture (see the [Web Frontend System](https://deepwiki.com/goauthentik/authentik/2-web-frontend-system)
|
|
116
|
-
overview). To add a stage component you **must** modify and rebuild the bundle
|
|
129
|
+
overview). To add a stage component you **must** modify and rebuild the bundle -
|
|
117
130
|
exactly what we do, and exactly what breaks.
|
|
118
131
|
|
|
119
132
|
### 2.3 What Authentik *does* support as extension points
|
|
120
133
|
|
|
121
134
|
- **Blueprints** ([docs](https://docs.goauthentik.io/customize/blueprints/)):
|
|
122
135
|
declarative YAML to create/configure stages, flows, providers, brands. This is
|
|
123
|
-
configuration-as-code, **not** a way to add *new stage types*
|
|
136
|
+
configuration-as-code, **not** a way to add *new stage types* - it can only
|
|
124
137
|
instantiate stage classes that already exist in the running image. (We use it
|
|
125
138
|
correctly to wire the flow once the class is baked in.)
|
|
126
139
|
- **The REST API / Terraform**: manage all objects externally. The sanctioned
|
|
127
140
|
"use the API" path.
|
|
128
141
|
- **Sources** ([docs](https://docs.goauthentik.io/users-sources/sources/)):
|
|
129
142
|
Authentik can *consume* external identity from OAuth/OIDC/SAML/LDAP/SCIM
|
|
130
|
-
sources. **This is the supported way to plug in a foreign IdP**
|
|
143
|
+
sources. **This is the supported way to plug in a foreign IdP** - and it is the
|
|
131
144
|
one extension point that fits CapAuth without touching Authentik's bundle (see
|
|
132
145
|
§4 Option C and §5).
|
|
133
146
|
- **Expression policies / property mappings**: Python snippets evaluated at
|
|
134
|
-
runtime
|
|
147
|
+
runtime - useful for claims logic, but cannot render a custom login UI or
|
|
135
148
|
implement a challenge/response stage.
|
|
136
149
|
- **`AUTHENTIK_*` env + `user_settings.py`**: configuration override hook. It
|
|
137
150
|
loads custom settings (and can append to `TENANT_APPS`), but that is settings
|
|
138
|
-
injection, not a stage-plugin API
|
|
151
|
+
injection, not a stage-plugin API - and per BeryJu it is not a supported way to
|
|
139
152
|
ship a custom Django app.
|
|
140
153
|
|
|
141
154
|
**Conclusion for §2:** Authentik has **rich configuration extensibility (blueprints,
|
|
@@ -169,8 +182,8 @@ open-core model, so a CLA may be requested in practice.
|
|
|
169
182
|
and the maintainers are converging on **passkeys/WebAuthn** (their MFA blog
|
|
170
183
|
argues phishing-resistant FIDO2 is the future:
|
|
171
184
|
[link](https://goauthentik.io/blog/2025-03-05-mfa-in-authentik/)). A
|
|
172
|
-
PGP-fingerprint primary-login stage
|
|
173
|
-
the user table is a key registry
|
|
185
|
+
PGP-fingerprint primary-login stage - where the fingerprint *is* the user and
|
|
186
|
+
the user table is a key registry - is a sovereign-identity philosophy that does
|
|
174
187
|
not match Authentik's user model (real `User` objects, brands, enterprise RBAC).
|
|
175
188
|
- **The custom-stage appetite is unproven.** The open feature request for
|
|
176
189
|
generic custom stages ([#17726](https://github.com/goauthentik/authentik/issues/17726))
|
|
@@ -187,51 +200,51 @@ duplicates the role of their passkey work and carries an unusual identity model.
|
|
|
187
200
|
Realistically that gets "interesting, but use the API / make it a Source."
|
|
188
201
|
Reframing CapAuth as an **OIDC/OAuth Source** (CapAuth service is the IdP,
|
|
189
202
|
Authentik consumes it) needs **zero** new built-in stage and uses an extension
|
|
190
|
-
point they actively support
|
|
203
|
+
point they actively support - that is far more upstream-friendly *and* removes our
|
|
191
204
|
web-patching problem entirely. (See §5.)
|
|
192
205
|
|
|
193
206
|
---
|
|
194
207
|
|
|
195
208
|
## 4. Options and tradeoffs
|
|
196
209
|
|
|
197
|
-
### Option A
|
|
210
|
+
### Option A - Upstream PR to Authentik core (the stage)
|
|
198
211
|
|
|
199
212
|
| | |
|
|
200
213
|
|---|---|
|
|
201
214
|
| **What** | Submit `CapAuthStage` + web component as a built-in stage PR. |
|
|
202
215
|
| **Maintenance** | Low *if merged* (they carry it). High *until* merged (rebase against a fast-moving codebase) and merge is uncertain. |
|
|
203
216
|
| **Version fragility** | Eliminated if merged (it's in-tree). |
|
|
204
|
-
| **Who can use it** | Everyone, out of the box
|
|
217
|
+
| **Who can use it** | Everyone, out of the box - best reach. |
|
|
205
218
|
| **Time cost** | High + unbounded: shape to their conventions, tests, review cycles, likely a CLA, likely rejection or "make it a Source." |
|
|
206
219
|
| **SKWorld fit** | Good if accepted (sovereign PGP login becomes mainstream IdP capability). Poor expected value given §3 acceptance odds. |
|
|
207
220
|
| **Verdict** | Don't lead with this for the *Stage*. Viable only if reframed as a *Source* (Option C/§5). |
|
|
208
221
|
|
|
209
|
-
### Option B
|
|
222
|
+
### Option B - Maintain the custom image fork (current state)
|
|
210
223
|
|
|
211
224
|
| | |
|
|
212
225
|
|---|---|
|
|
213
226
|
| **What** | Keep `Dockerfile.authentik-capauth`, rebuild + re-patch per version. |
|
|
214
|
-
| **Maintenance** | **High and recurring.** Re-patch internal files, fight the esbuild `createRef` bug, re-`npm ci`, re-verify the component renders, re-handle py-minor/imghdr drift, re-test flow internals
|
|
227
|
+
| **Maintenance** | **High and recurring.** Re-patch internal files, fight the esbuild `createRef` bug, re-`npm ci`, re-verify the component renders, re-handle py-minor/imghdr drift, re-test flow internals - every bump. |
|
|
215
228
|
| **Version fragility** | **Worst of all options.** Breaks on web-bundle internals each release; the web build is *currently broken*, so the headline feature (browser PGP form) doesn't ship today. |
|
|
216
229
|
| **Who can use it** | Only us (and anyone who pulls our ghcr image and trusts it). |
|
|
217
230
|
| **Time cost** | Recurring engineer-days per Authentik release, indefinitely. |
|
|
218
231
|
| **SKWorld fit** | Centralized SSO is attractive, but a fork that breaks on every bump and can't render its own UI is a liability, not an asset. |
|
|
219
232
|
| **Verdict** | Not sustainable as the primary path. At most keep a **backend-only** variant (no web rebuild) for API/headless use. |
|
|
220
233
|
|
|
221
|
-
### Option C
|
|
234
|
+
### Option C - Redistributable Authentik integration (no core fork)
|
|
222
235
|
|
|
223
236
|
Two sub-flavors, both avoiding the web-bundle patch:
|
|
224
237
|
|
|
225
|
-
**C1
|
|
238
|
+
**C1 - Backend-only custom Django app, stock frontend.** Ship the `capauth`
|
|
226
239
|
Django app as a layer on the *unmodified* official image (the cap9+ reality
|
|
227
240
|
already does this), wire it via blueprint, and **don't** ship a web component.
|
|
228
241
|
The stage works via the flow-executor API / headless / CLI / extension clients,
|
|
229
242
|
not the browser form.
|
|
230
243
|
|
|
231
|
-
**C2
|
|
244
|
+
**C2 - CapAuth as an OIDC/OAuth *Source* (recommended sub-flavor).** Run the
|
|
232
245
|
existing standalone CapAuth service (`ghcr.io/smilintux/capauth`) as the IdP;
|
|
233
246
|
register it in Authentik as an **OAuth/OIDC Source**. The browser does PGP login
|
|
234
|
-
*on CapAuth's own page* (which we fully control
|
|
247
|
+
*on CapAuth's own page* (which we fully control - no Authentik bundle), then
|
|
235
248
|
Authentik federates the identity in. Authentik then fans out SSO to all
|
|
236
249
|
downstream apps.
|
|
237
250
|
|
|
@@ -244,16 +257,16 @@ downstream apps.
|
|
|
244
257
|
| **Time cost** | Low ongoing; medium to build a clean redistributable. | Medium one-time to build the OIDC IdP endpoints in the CapAuth service; then near-zero. |
|
|
245
258
|
| **SKWorld fit** | OK as a headless/API capability. | **Excellent:** centralized SSO from one PGP login, sovereign service we own, no fork. |
|
|
246
259
|
|
|
247
|
-
### Option D
|
|
260
|
+
### Option D - Drop Authentik; native per-app CapAuth plugins
|
|
248
261
|
|
|
249
262
|
| | |
|
|
250
263
|
|---|---|
|
|
251
264
|
| **What** | Each app gets a native CapAuth plugin using *that app's* supported extension API. **Nextcloud is done and proven.** |
|
|
252
|
-
| **Evidence** | `src/capauth/integrations/nextcloud/` is a complete, idiomatic Nextcloud app: real `IUserBackend` (`lib/User/Backend.php`), `AlternativeLogin/CapAuthLogin.php` ("Sign in with CapAuth" button), challenge/verifier/provisioning/group-sync services, DB migration, nonce-prune background job, registered via `appinfo/info.xml`. It is **passwordless PRIMARY login in a real browser**
|
|
265
|
+
| **Evidence** | `src/capauth/integrations/nextcloud/` is a complete, idiomatic Nextcloud app: real `IUserBackend` (`lib/User/Backend.php`), `AlternativeLogin/CapAuthLogin.php` ("Sign in with CapAuth" button), challenge/verifier/provisioning/group-sync services, DB migration, nonce-prune background job, registered via `appinfo/info.xml`. It is **passwordless PRIMARY login in a real browser** - the thing the Authentik fork can't currently do. |
|
|
253
266
|
| **Maintenance** | Per-app, but each uses *supported* extension points (stable, documented), so far less fragile than patching Authentik's bundle. Cost scales with number of apps. |
|
|
254
267
|
| **Version fragility** | Low per app (app APIs are stable contracts). |
|
|
255
|
-
| **Who can use it** | Anyone running that app
|
|
256
|
-
| **Time cost** | One plugin per target app (Forgejo scaffold exists; others TBD). No central SSO
|
|
268
|
+
| **Who can use it** | Anyone running that app - and it's publishable to the app's marketplace (Nextcloud app store), real reach. |
|
|
269
|
+
| **Time cost** | One plugin per target app (Forgejo scaffold exists; others TBD). No central SSO - N integrations for N apps. |
|
|
257
270
|
| **SKWorld fit** | **Excellent for sovereignty** (no central dependency, each app fully owned), **weak for scale** (no single login → many apps; re-implement per ecosystem). |
|
|
258
271
|
|
|
259
272
|
---
|
|
@@ -262,32 +275,32 @@ downstream apps.
|
|
|
262
275
|
|
|
263
276
|
**Adopt a two-track strategy. Retire the web-patching fork as the primary path.**
|
|
264
277
|
|
|
265
|
-
### Track 1 (now): native per-app plugins are the default sovereign login
|
|
278
|
+
### Track 1 (now): native per-app plugins are the default sovereign login - Option D
|
|
266
279
|
|
|
267
280
|
Nextcloud already delivers what the Authentik fork promised: **passwordless PGP
|
|
268
281
|
PRIMARY login that renders in a real browser**, via Nextcloud's *supported*
|
|
269
282
|
extension points. Make this the canonical CapAuth login experience for our
|
|
270
283
|
highest-value apps. It is sovereign, marketplace-publishable, and not fragile.
|
|
271
|
-
Prioritize the next 1
|
|
284
|
+
Prioritize the next 1-2 apps by actual need (Forgejo scaffold already exists).
|
|
272
285
|
|
|
273
|
-
### Track 2 (next): centralized SSO via CapAuth-as-OIDC-Source
|
|
286
|
+
### Track 2 (next): centralized SSO via CapAuth-as-OIDC-Source - Option C2
|
|
274
287
|
|
|
275
288
|
For the "one PGP login → many apps" value that only an IdP gives, **do not** keep
|
|
276
289
|
fighting Authentik's bundle. Instead:
|
|
277
290
|
|
|
278
291
|
1. Add OIDC/OAuth2 *provider* endpoints to the standalone CapAuth service
|
|
279
292
|
(authorize/token/userinfo/jwks) so it is a real IdP. The PGP challenge UI
|
|
280
|
-
lives on **CapAuth's own page**
|
|
293
|
+
lives on **CapAuth's own page** - fully ours, zero Authentik web patching.
|
|
281
294
|
2. Register CapAuth in **stock** Authentik as an **OAuth/OIDC Source**. Authentik
|
|
282
295
|
then fans SSO out to every downstream app it fronts.
|
|
283
296
|
3. This uses an extension point Authentik *actively supports*, runs on the
|
|
284
297
|
**official unmodified image**, and is decoupled from Authentik internals via
|
|
285
|
-
the stable OIDC standard
|
|
298
|
+
the stable OIDC standard - eliminating the version-bump treadmill.
|
|
286
299
|
|
|
287
300
|
### What to do with the existing fork: downgrade, don't delete
|
|
288
301
|
|
|
289
302
|
- **Stop shipping the web-builder stage.** It's already disabled; make that
|
|
290
|
-
permanent. Do not invest more in the esbuild `createRef` fix
|
|
303
|
+
permanent. Do not invest more in the esbuild `createRef` fix - there is no
|
|
291
304
|
supported home for a custom stage component, so even a fixed build re-breaks
|
|
292
305
|
next release.
|
|
293
306
|
- **Keep the backend Django app (Option C1) only as a headless/API capability**
|
|
@@ -310,7 +323,7 @@ likely to be accepted. A PGP *Stage* PR is low-EV and should not be our first mo
|
|
|
310
323
|
- It **keeps both strategic values**: sovereignty + working browser login (Track 1,
|
|
311
324
|
proven) and centralized SSO from one PGP login (Track 2, on stock Authentik).
|
|
312
325
|
- It moves us onto **supported extension points everywhere** (Nextcloud app API;
|
|
313
|
-
Authentik Sources/OIDC) instead of patching internals
|
|
326
|
+
Authentik Sources/OIDC) instead of patching internals - slashing
|
|
314
327
|
version-bump fragility.
|
|
315
328
|
- It is **honest about what ships today**: the fork's headline feature doesn't
|
|
316
329
|
render in a browser; Nextcloud's does.
|
|
@@ -319,11 +332,11 @@ likely to be accepted. A PGP *Stage* PR is low-EV and should not be our first mo
|
|
|
319
332
|
|
|
320
333
|
## 6. Concrete next steps
|
|
321
334
|
|
|
322
|
-
1. **Decision sign-off (Chef):**
|
|
335
|
+
1. **Decision sign-off (Chef):** done, see Status (C2 / Track 2). Mark the
|
|
323
336
|
web-patching fork as deprecated-for-browser-use.
|
|
324
337
|
2. **Track 1:** publish/polish the Nextcloud CapAuth app (it's complete); pick
|
|
325
338
|
the next target app (Forgejo scaffold → finish, or another high-use app).
|
|
326
|
-
3. **Track 2 (
|
|
339
|
+
3. **Track 2 (decided; lab proof pending, see the cutover plan):** add OIDC provider endpoints to the standalone CapAuth
|
|
327
340
|
service; stand up stock Authentik with CapAuth registered as an OAuth/OIDC
|
|
328
341
|
**Source**; prove PGP-login→Authentik-session→downstream-app SSO E2E on `.13`.
|
|
329
342
|
This replaces the cap-image deploy.
|
|
@@ -337,7 +350,7 @@ likely to be accepted. A PGP *Stage* PR is low-EV and should not be our first mo
|
|
|
337
350
|
|
|
338
351
|
## Sources
|
|
339
352
|
|
|
340
|
-
- BeryJu (authentik founder) on custom plugins
|
|
353
|
+
- BeryJu (authentik founder) on custom plugins - "merge upstream, or use the API":
|
|
341
354
|
<https://github.com/goauthentik/authentik/issues/1541> (verified via GitHub API)
|
|
342
355
|
- Custom stages feature request (open, `status/reviewing`, no maintainer commitment):
|
|
343
356
|
<https://github.com/goauthentik/authentik/issues/17726>
|
|
@@ -350,13 +363,13 @@ likely to be accepted. A PGP *Stage* PR is low-EV and should not be our first mo
|
|
|
350
363
|
<https://docs.goauthentik.io/add-secure-apps/flows-stages/stages/>
|
|
351
364
|
- Blueprints (declarative config of existing objects, not new stage types):
|
|
352
365
|
<https://docs.goauthentik.io/customize/blueprints/>
|
|
353
|
-
- Sources (supported way to federate external IdPs
|
|
366
|
+
- Sources (supported way to federate external IdPs - the C2 path):
|
|
354
367
|
<https://docs.goauthentik.io/users-sources/sources/>
|
|
355
368
|
- WebAuthn / FIDO2 / Passkeys stage (existing passwordless precedent + direction):
|
|
356
369
|
<https://docs.goauthentik.io/add-secure-apps/flows-stages/stages/authenticator_webauthn/>
|
|
357
370
|
- MFA direction blog (phishing-resistant FIDO2/passkeys as the priority):
|
|
358
371
|
<https://goauthentik.io/blog/2025-03-05-mfa-in-authentik/>
|
|
359
|
-
- Release 2026.5 (WebAuthn L3 hints
|
|
372
|
+
- Release 2026.5 (WebAuthn L3 hints - ongoing passkey investment):
|
|
360
373
|
<https://docs.goauthentik.io/releases/2026.5/>
|
|
361
374
|
- Flows/stages/policies explainer: <https://goauthentik.io/blog/2024-08-27-flows-stages-and-policies/>
|
|
362
375
|
|
|
@@ -370,3 +383,135 @@ likely to be accepted. A PGP *Stage* PR is low-EV and should not be our first mo
|
|
|
370
383
|
`src/capauth/integrations/nextcloud/` (`lib/User/Backend.php`,
|
|
371
384
|
`lib/AlternativeLogin/CapAuthLogin.php`)
|
|
372
385
|
- Deploy history / E2E-API-only proof: `HANDOFF-capauth-authentik-2026-06-17.md`
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## 2026-10-23 cutover plan (nor, as part of the 2026.8.5 upgrade)
|
|
391
|
+
|
|
392
|
+
Chef's decision is Option C2 / Track 2 (CapAuth as an OIDC/OAuth Source on stock
|
|
393
|
+
Authentik). This section records the concrete cutover plan for **nor**, the only
|
|
394
|
+
estate still running the `Dockerfile.authentik-capauth` fork. NAM is unaffected
|
|
395
|
+
(always ran stock Authentik, never had the fork).
|
|
396
|
+
|
|
397
|
+
### What changes
|
|
398
|
+
|
|
399
|
+
- nor's `sksso-prod_server`/`_worker` move from the custom image
|
|
400
|
+
(`skgit.skstack01.douno.it/skadmin/authentik-capauth:*`) to the **stock**
|
|
401
|
+
`ghcr.io/goauthentik/server:2026.8.5` image. NAM never ran the fork. Its
|
|
402
|
+
current Authentik version is not recorded in this repo (the scope paragraph at
|
|
403
|
+
the top says 2026.2.7 after the tactical patch); open question, confirm on NAM.
|
|
404
|
+
- The sksso role's `sksso.CAPAUTH_ENABLED: true` path (documented in
|
|
405
|
+
`v1/ansible/optional/sksso/README.md`, "CapAuth login (optional)") replaces
|
|
406
|
+
the baked-in stage: the standalone `capauth` service becomes an Authentik
|
|
407
|
+
**OAuth Source**, with its own login flow, instead of a flow stage compiled
|
|
408
|
+
into Authentik's bundle. This is already-shipped, already-tested code (commit
|
|
409
|
+
`ecc8e50`, "per-client require_nonce so stock Authentik's OAuth source can
|
|
410
|
+
log in"), not new engineering.
|
|
411
|
+
- The fork-only CapAuth objects are the ones the fork's blueprint
|
|
412
|
+
(`src/capauth/authentik/blueprints/capauth-pgp-login.yaml`) creates: the
|
|
413
|
+
`capauth.capauthstage` instance `capauth-pgp`, the authentication flow with
|
|
414
|
+
slug `capauth-authentication`, and that flow's two stage bindings (CapAuthStage
|
|
415
|
+
at order 0, `default-authentication-login` at order 10), plus the fork app's
|
|
416
|
+
tables (`CapAuthStage`, `CapAuthKeyRegistry`). Those are what a later cleanup
|
|
417
|
+
may retire. Flow `97730dbd-b5fc-4171-8dce-4de5273c1db2` is NOT one of them: it
|
|
418
|
+
is the general `skstack01-application-authorization` flow that apps such as
|
|
419
|
+
Forgejo use (see `AUTHENTIK_FORGEJO_DEPLOYMENT.md`), and it must not be
|
|
420
|
+
retired. `AUTHENTIK_DEPLOYMENT_SKSSO.md` describes adding a CapAuth stage
|
|
421
|
+
binding to that flow. Open question: whether that binding was actually added
|
|
422
|
+
on nor; if so, only that binding is fork-only, and it must be unbound without
|
|
423
|
+
touching the flow itself.
|
|
424
|
+
- Slug clash: the fork's blueprint flow slug `capauth-authentication` is also
|
|
425
|
+
the default `CAPAUTH_FLOW_SLUG` of `tasks/capauth_provision.yml`. While the
|
|
426
|
+
fork still runs, the stock OAuth-source flow MUST be provisioned with a
|
|
427
|
+
distinct slug (for example `capauth-source-authentication`, set through
|
|
428
|
+
`CAPAUTH_FLOW_SLUG`), or provisioning would overwrite the fork's flow. Open
|
|
429
|
+
question: confirm the role honours the override in the lab before relying on
|
|
430
|
+
it; if it does not, a parallel run on the same instance is not possible and
|
|
431
|
+
step L3 below must be dropped in favour of a separate lab instance.
|
|
432
|
+
- The old fork objects are NOT touched automatically; retiring them is a
|
|
433
|
+
manual admin-UI cleanup step after the new flow is proven (see "Rollback" in
|
|
434
|
+
the README's CapAuth section for the exact unbind order, run in reverse as an
|
|
435
|
+
adopt order).
|
|
436
|
+
- Enrolled users move from the fork's `CapAuthKeyRegistry` (one row per PGP
|
|
437
|
+
fingerprint, no linked Authentik user) to `sksso.CAPAUTH_USERS`
|
|
438
|
+
(fingerprint maps to an existing Authentik user). Every current nor CapAuth
|
|
439
|
+
user must be re-enrolled against an actual Authentik user account before
|
|
440
|
+
cutover, or their login breaks. This is the one step with real user-facing
|
|
441
|
+
migration risk and needs its own checklist before the lab run.
|
|
442
|
+
|
|
443
|
+
### Order of operations (lab first, skstack06, before any nor change)
|
|
444
|
+
|
|
445
|
+
The order runs from the fork to stock with CapAuth as an OAuth Source. The fork
|
|
446
|
+
is retired FIRST, at nor's current Authentik version, and the stock upgrade hops
|
|
447
|
+
come AFTER on the stock image. Reason: upgrading the fork through the
|
|
448
|
+
intermediate versions would mean rebuilding it against each one for no benefit.
|
|
449
|
+
Lab steps (L) may restore dumps freely. Production steps (P) never restore a
|
|
450
|
+
dump; rollback on nor is the separate conditional section below.
|
|
451
|
+
|
|
452
|
+
Lab (skstack06):
|
|
453
|
+
|
|
454
|
+
- L1. Reproduce nor's real pre-cutover shape: nor currently runs the fork image
|
|
455
|
+
(`Dockerfile.authentik-capauth`) on the 2025.12.6 line, so build
|
|
456
|
+
`authentik-capauth:2025.12.6` on skstack06 and deploy the sksso role with it.
|
|
457
|
+
Open question: confirm the exact fork image tag and Authentik version running
|
|
458
|
+
on nor today.
|
|
459
|
+
- L2. Seed representative data: a handful of users and groups, at least one OIDC
|
|
460
|
+
provider, the embedded outpost plus a forward-auth proxy provider, and enough
|
|
461
|
+
CapAuth-fork enrollments (`CapAuthKeyRegistry` rows) to exercise the migration.
|
|
462
|
+
- L3. Parallel-run: enable `sksso.CAPAUTH_ENABLED: true` alongside the
|
|
463
|
+
still-running fork, with a distinct `CAPAUTH_FLOW_SLUG` (see "Slug clash"
|
|
464
|
+
above), bring up the `capauth` service and OAuth source, and prove login
|
|
465
|
+
through the new path end to end (challenge and verify, OAuth source login, SSO
|
|
466
|
+
fan-out) while the fork path still works.
|
|
467
|
+
- L4. Prepare the user migration: map each fork enrollment (PGP fingerprint) to
|
|
468
|
+
an existing Authentik user in `sksso.CAPAUTH_USERS`. Open question: the list of
|
|
469
|
+
current nor CapAuth users and the migration checklist do not exist yet and
|
|
470
|
+
must be written before L5.
|
|
471
|
+
- L5. Lab cutover, fork to stock at the SAME version: take a dump, swap the fork
|
|
472
|
+
image for the stock `ghcr.io/goauthentik/server` image at 2025.12.6, keep
|
|
473
|
+
`CAPAUTH_ENABLED: true`, and re-verify every login path (password, OIDC apps,
|
|
474
|
+
forward-auth, the CapAuth OAuth source). Then, lab only, rehearse the rollback:
|
|
475
|
+
restore the dump and confirm the fork image still boots against it. Open
|
|
476
|
+
question: whether the stock image runs cleanly against a database that carries
|
|
477
|
+
the fork's extra tables and migrations is untested.
|
|
478
|
+
- L6. Lab upgrade on stock: 2025.12.6 to 2026.2.7 to 2026.5.7 to 2026.8.5, with
|
|
479
|
+
the L5 login-path checks repeated at each hop.
|
|
480
|
+
|
|
481
|
+
Production (nor), only after L1 to L6 pass end to end:
|
|
482
|
+
|
|
483
|
+
- P1. Take and verify a pre-cutover database dump and record the running fork
|
|
484
|
+
image tag. Open question: the nor change window and change approval record
|
|
485
|
+
are not captured here.
|
|
486
|
+
- P2. Parallel-run: enable `CAPAUTH_ENABLED: true` with the distinct
|
|
487
|
+
`CAPAUTH_FLOW_SLUG` alongside the running fork and prove the new login path.
|
|
488
|
+
- P3. Complete the user migration (the L4 checklist) so every CapAuth user maps
|
|
489
|
+
to an Authentik user.
|
|
490
|
+
- P4. Cutover: swap the fork image for stock at the current version, re-verify
|
|
491
|
+
every login path.
|
|
492
|
+
- P5. Upgrade on stock through the same hops as L6, verifying login paths at
|
|
493
|
+
each hop.
|
|
494
|
+
|
|
495
|
+
### Rollback on nor (conditional, not a plan step)
|
|
496
|
+
|
|
497
|
+
Only if a production step fails verification. Dump restore is destructive for
|
|
498
|
+
anything written after the dump (new users, sessions, enrollments), so a restore
|
|
499
|
+
needs an explicit decision at the time and is never run as part of P1 to P5. The
|
|
500
|
+
options, in order of preference: (1) revert the image reference to the recorded
|
|
501
|
+
fork tag if the database was not migrated forward; (2) restore the P1 dump only
|
|
502
|
+
once the data written since has been accounted for. Open question: which of
|
|
503
|
+
these is viable after P4 depends on the untested L5 stock-on-fork-database
|
|
504
|
+
question above.
|
|
505
|
+
|
|
506
|
+
### Fork retirement (after the lab proof and after nor is cut over)
|
|
507
|
+
|
|
508
|
+
- Freeze `Dockerfile.authentik-capauth` and
|
|
509
|
+
`scripts/build_authentik_capauth_image.sh`: add a banner pointing at this
|
|
510
|
+
decision and `CAPAUTH_ENABLED`, do not delete (historical reference and the
|
|
511
|
+
one documented rollback path if the Source integration needs to be backed
|
|
512
|
+
out urgently).
|
|
513
|
+
- Archive the `release/authentik-capauth-cap10`, `cap11`, `cap12` branches (do
|
|
514
|
+
not force-delete; they are the build history for the fork, useful if anyone
|
|
515
|
+
needs to reconstruct exactly what nor ran).
|
|
516
|
+
- Update `docs/authentik-capauth.md` with a top banner: "superseded by
|
|
517
|
+
CAPAUTH_ENABLED, see AUTHENTIK_STRATEGY_DECISION.md".
|
|
@@ -45,8 +45,8 @@ gnupg = [
|
|
|
45
45
|
service = [
|
|
46
46
|
"fastapi>=0.110",
|
|
47
47
|
"uvicorn[standard]>=0.27",
|
|
48
|
-
"python-multipart>=0.0.
|
|
49
|
-
"PyJWT>=2.
|
|
48
|
+
"python-multipart>=0.0.31",
|
|
49
|
+
"PyJWT>=2.15.0",
|
|
50
50
|
"python-gnupg>=0.5",
|
|
51
51
|
"httpx>=0.25",
|
|
52
52
|
"segno>=1.6",
|
|
@@ -62,7 +62,7 @@ dev = [
|
|
|
62
62
|
"python-gnupg>=0.5",
|
|
63
63
|
"black>=24.0",
|
|
64
64
|
"ruff>=0.3",
|
|
65
|
-
"zeroconf>=0.
|
|
65
|
+
"zeroconf>=0.149.16",
|
|
66
66
|
"webauthn>=2.0",
|
|
67
67
|
"soft-webauthn>=0.1",
|
|
68
68
|
"pywebpush>=1.14",
|