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.
Files changed (414) hide show
  1. capauth-0.3.14/AGENTS.md +99 -0
  2. {capauth-0.3.13 → capauth-0.3.14}/CHANGELOG.md +11 -0
  3. {capauth-0.3.13 → capauth-0.3.14}/Dockerfile.authentik-capauth +22 -5
  4. {capauth-0.3.13/src/capauth.egg-info → capauth-0.3.14}/PKG-INFO +4 -4
  5. {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_STRATEGY_DECISION.md +188 -43
  6. {capauth-0.3.13 → capauth-0.3.14}/pyproject.toml +3 -3
  7. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integration.py +3 -3
  8. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/provider.py +87 -16
  9. {capauth-0.3.13 → capauth-0.3.14/src/capauth.egg-info}/PKG-INFO +4 -4
  10. {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/SOURCES.txt +1 -2
  11. {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/requires.txt +3 -3
  12. {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/scm_file_list.json +1 -2
  13. {capauth-0.3.13 → capauth-0.3.14}/tests/test_integration.py +14 -3
  14. capauth-0.3.14/tests/test_oidc_login_passphrase_dialog.py +38 -0
  15. {capauth-0.3.13 → capauth-0.3.14}/urllib.error +1 -1
  16. capauth-0.3.13/.cursorrules +0 -15
  17. capauth-0.3.13/AGENTS.md +0 -24
  18. capauth-0.3.13/CLAUDE.md +0 -144
  19. {capauth-0.3.13 → capauth-0.3.14}/.dockerignore +0 -0
  20. {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/ci.yml +0 -0
  21. {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/docs-check.yml +0 -0
  22. {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/image.yml +0 -0
  23. {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/nextcloud-appstore.yml +0 -0
  24. {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/publish.yml +0 -0
  25. {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/pytest.yml +0 -0
  26. {capauth-0.3.13 → capauth-0.3.14}/.github/workflows/secret-scan.yml +0 -0
  27. {capauth-0.3.13 → capauth-0.3.14}/.gitignore +0 -0
  28. {capauth-0.3.13 → capauth-0.3.14}/.gitleaks-baseline.json +0 -0
  29. {capauth-0.3.13 → capauth-0.3.14}/.gitleaks.toml +0 -0
  30. {capauth-0.3.13 → capauth-0.3.14}/AI-ADVOCATE.md +0 -0
  31. {capauth-0.3.13 → capauth-0.3.14}/ARCHITECTURE.md +0 -0
  32. {capauth-0.3.13 → capauth-0.3.14}/CODE_OF_CONDUCT.md +0 -0
  33. {capauth-0.3.13 → capauth-0.3.14}/CONTRIBUTING.md +0 -0
  34. {capauth-0.3.13 → capauth-0.3.14}/Dockerfile +0 -0
  35. {capauth-0.3.13 → capauth-0.3.14}/LICENSE +0 -0
  36. {capauth-0.3.13 → capauth-0.3.14}/MANIFEST.in +0 -0
  37. {capauth-0.3.13 → capauth-0.3.14}/MISSION.md +0 -0
  38. {capauth-0.3.13 → capauth-0.3.14}/README.md +0 -0
  39. {capauth-0.3.13 → capauth-0.3.14}/SECURITY.md +0 -0
  40. {capauth-0.3.13 → capauth-0.3.14}/SKILL.md +0 -0
  41. {capauth-0.3.13 → capauth-0.3.14}/SOP.md +0 -0
  42. {capauth-0.3.13 → capauth-0.3.14}/authentik-custom/capauth_migrate.py +0 -0
  43. {capauth-0.3.13 → capauth-0.3.14}/authentik-custom/imghdr.py +0 -0
  44. {capauth-0.3.13 → capauth-0.3.14}/authentik-custom/user_settings.py +0 -0
  45. {capauth-0.3.13 → capauth-0.3.14}/bin/cli.js +0 -0
  46. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/.gitignore +0 -0
  47. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/README.md +0 -0
  48. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/RELEASING.md +0 -0
  49. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/background.js +0 -0
  50. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/autofill.js +0 -0
  51. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/cross_origin_signing.js +0 -0
  52. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/detector.js +0 -0
  53. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/provider.js +0 -0
  54. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/content_scripts/provider_bridge.js +0 -0
  55. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon.svg +0 -0
  56. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon128.png +0 -0
  57. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon16.png +0 -0
  58. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/icons/icon48.png +0 -0
  59. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/bunker-e2e.js +0 -0
  60. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/keyqr.js +0 -0
  61. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/keyvault.js +0 -0
  62. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/openpgp.js +0 -0
  63. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/lib/signer-backends.js +0 -0
  64. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/manifest.firefox.json +0 -0
  65. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/manifest.json +0 -0
  66. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/native-host/capauth_signer.py +0 -0
  67. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/native-host/com.capauth.signer.json +0 -0
  68. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/native-host/install.sh +0 -0
  69. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/options/options.html +0 -0
  70. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/options/options.js +0 -0
  71. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/package-lock.json +0 -0
  72. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/package.json +0 -0
  73. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/popup/popup.css +0 -0
  74. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/popup/popup.html +0 -0
  75. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/popup/popup.js +0 -0
  76. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/scripts/build.js +0 -0
  77. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/scripts/generate-icons.js +0 -0
  78. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/AuthenticatorSelectionStage.js +0 -0
  79. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/CapAuthStage.js +0 -0
  80. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/QRDisplayStage.js +0 -0
  81. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/SignatureVerificationStage.js +0 -0
  82. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/stages/StagePipeline.js +0 -0
  83. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/submission/STORE_LISTING.md +0 -0
  84. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/submission/privacy-policy.md +0 -0
  85. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/fixtures/test_key.json +0 -0
  86. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/background.test.js +0 -0
  87. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/bunker_e2e.test.js +0 -0
  88. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/detector.test.js +0 -0
  89. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/keyqr.test.js +0 -0
  90. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/keyvault.test.js +0 -0
  91. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/openpgp.test.js +0 -0
  92. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/provider_api.test.js +0 -0
  93. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/provider_tierb.test.js +0 -0
  94. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/remote_bunker.test.js +0 -0
  95. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/tests/unit/signer_backends.test.js +0 -0
  96. {capauth-0.3.13 → capauth-0.3.14}/browser-extension/vitest.config.js +0 -0
  97. {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/.env.example +0 -0
  98. {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/deploy.sh +0 -0
  99. {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/docker-compose.yml +0 -0
  100. {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/systemd/capauth-backup.service +0 -0
  101. {capauth-0.3.13 → capauth-0.3.14}/deploy/capauth-service/systemd/capauth-backup.timer +0 -0
  102. {capauth-0.3.13 → capauth-0.3.14}/deploy/forgejo-capauth/.env.example +0 -0
  103. {capauth-0.3.13 → capauth-0.3.14}/deploy/forgejo-capauth/docker-compose.yml +0 -0
  104. {capauth-0.3.13 → capauth-0.3.14}/deploy/forgejo-capauth/preflight.sh +0 -0
  105. {capauth-0.3.13 → capauth-0.3.14}/docs/AIRGAPPED_SIGNING_WORKSTATION.md +0 -0
  106. {capauth-0.3.13 → capauth-0.3.14}/docs/ARCHITECTURE.md +0 -0
  107. {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_CUSTOM_STAGE.md +0 -0
  108. {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_DEPLOYMENT_SKSSO.md +0 -0
  109. {capauth-0.3.13 → capauth-0.3.14}/docs/AUTHENTIK_FORGEJO_DEPLOYMENT.md +0 -0
  110. {capauth-0.3.13 → capauth-0.3.14}/docs/CAPAUTH-WEBAUTHN-05-QUALIFICATION.md +0 -0
  111. {capauth-0.3.13 → capauth-0.3.14}/docs/CAPAUTH_BUNKER_REMOTE_SIGNER.md +0 -0
  112. {capauth-0.3.13 → capauth-0.3.14}/docs/CAPAUTH_OIDC_IDP.md +0 -0
  113. {capauth-0.3.13 → capauth-0.3.14}/docs/CLAIMS.md +0 -0
  114. {capauth-0.3.13 → capauth-0.3.14}/docs/COLD_MACHINE_BOOTSTRAP_AND_DR.md +0 -0
  115. {capauth-0.3.13 → capauth-0.3.14}/docs/CRYPTO_SPEC.md +0 -0
  116. {capauth-0.3.13 → capauth-0.3.14}/docs/DELEGATED_CAPABILITIES.md +0 -0
  117. {capauth-0.3.13 → capauth-0.3.14}/docs/DOWNSTREAM_DURABLE_BACKENDS.md +0 -0
  118. {capauth-0.3.13 → capauth-0.3.14}/docs/ENTERPRISE_MANAGED_KEYS.md +0 -0
  119. {capauth-0.3.13 → capauth-0.3.14}/docs/HUMAN_IDENTITY_SETUP_AND_ROTATION.md +0 -0
  120. {capauth-0.3.13 → capauth-0.3.14}/docs/IDENTITY_ESTATE.md +0 -0
  121. {capauth-0.3.13 → capauth-0.3.14}/docs/INTEGRATION_BLUEPRINT.md +0 -0
  122. {capauth-0.3.13 → capauth-0.3.14}/docs/M0-capauth-api-v1.md +0 -0
  123. {capauth-0.3.13 → capauth-0.3.14}/docs/M0-capauth-importer-inventory.md +0 -0
  124. {capauth-0.3.13 → capauth-0.3.14}/docs/PASSPHRASE_ROTATION.md +0 -0
  125. {capauth-0.3.13 → capauth-0.3.14}/docs/PQC_CAPAUTH_REVISIT.md +0 -0
  126. {capauth-0.3.13 → capauth-0.3.14}/docs/PQC_ROOT_MIGRATION.md +0 -0
  127. {capauth-0.3.13 → capauth-0.3.14}/docs/PROTOCOL.md +0 -0
  128. {capauth-0.3.13 → capauth-0.3.14}/docs/ROOT_ROTATION_CEREMONY.md +0 -0
  129. {capauth-0.3.13 → capauth-0.3.14}/docs/SIGN_CHALLENGE.md +0 -0
  130. {capauth-0.3.13 → capauth-0.3.14}/docs/SKDASHBOARD_CONTROL_PLANE_POLICY.md +0 -0
  131. {capauth-0.3.13 → capauth-0.3.14}/docs/TRUST_GRAPH_COORD_PROJECTION.md +0 -0
  132. {capauth-0.3.13 → capauth-0.3.14}/docs/ZERO_KNOWLEDGE_PROFILE.md +0 -0
  133. {capauth-0.3.13 → capauth-0.3.14}/docs/audits/BLAST-RADIUS-CAPAUTH-01.md +0 -0
  134. {capauth-0.3.13 → capauth-0.3.14}/docs/audits/BLAST-RADIUS-CAPAUTH-01.sha256 +0 -0
  135. {capauth-0.3.13 → capauth-0.3.14}/docs/authentik-capauth.md +0 -0
  136. {capauth-0.3.13 → capauth-0.3.14}/docs/deploy-plan/capauth-bulletproof-deploy.md +0 -0
  137. {capauth-0.3.13 → capauth-0.3.14}/docs/evidence/capauth/SKL-CAPAUTH-SIGNER-P3P-MUTATION-ENVELOPE-2026-08-25.json +0 -0
  138. {capauth-0.3.13 → capauth-0.3.14}/docs/evidence/capauth/SKL-CAPAUTH-SIGNER-P3P-ROSTER-2026-08-25.json +0 -0
  139. {capauth-0.3.13 → capauth-0.3.14}/index.d.ts +0 -0
  140. {capauth-0.3.13 → capauth-0.3.14}/index.js +0 -0
  141. {capauth-0.3.13 → capauth-0.3.14}/openclaw-plugin.archived-2026-04-23/package.json +0 -0
  142. {capauth-0.3.13 → capauth-0.3.14}/openclaw-plugin.archived-2026-04-23/src/index.ts +0 -0
  143. {capauth-0.3.13 → capauth-0.3.14}/openclaw-plugin.archived-2026-04-23/src/openclaw.plugin.json +0 -0
  144. {capauth-0.3.13 → capauth-0.3.14}/package.json +0 -0
  145. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/app.js +0 -0
  146. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/icons/icon-192.png +0 -0
  147. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/icons/icon-512.png +0 -0
  148. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/index.html +0 -0
  149. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/bunker-e2e.js +0 -0
  150. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/bunker-signer.js +0 -0
  151. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/canonical.js +0 -0
  152. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/keyqr.js +0 -0
  153. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/lib/keyvault.js +0 -0
  154. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/manifest.webmanifest +0 -0
  155. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/sw.js +0 -0
  156. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/vendor/openpgp.min.js +0 -0
  157. {capauth-0.3.13 → capauth-0.3.14}/phone-signer/vendor/qrcode-generator.js +0 -0
  158. {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
  159. {capauth-0.3.13 → capauth-0.3.14}/scripts/build_authentik_capauth_image.sh +0 -0
  160. {capauth-0.3.13 → capauth-0.3.14}/scripts/capauth-backup.sh +0 -0
  161. {capauth-0.3.13 → capauth-0.3.14}/scripts/capauth-restore.sh +0 -0
  162. {capauth-0.3.13 → capauth-0.3.14}/scripts/gitleaks-scope.sh +0 -0
  163. {capauth-0.3.13 → capauth-0.3.14}/scripts/migrate_canonical_subjects.py +0 -0
  164. {capauth-0.3.13 → capauth-0.3.14}/scripts/pqc_ceremony_dryrun.py +0 -0
  165. {capauth-0.3.13 → capauth-0.3.14}/scripts/provision_agent_profiles.py +0 -0
  166. {capauth-0.3.13 → capauth-0.3.14}/setup.cfg +0 -0
  167. {capauth-0.3.13 → capauth-0.3.14}/skill.yaml +0 -0
  168. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/__init__.py +0 -0
  169. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/agent_identity.py +0 -0
  170. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/apps.py +0 -0
  171. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/__init__.py +0 -0
  172. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/api.py +0 -0
  173. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/blueprints/capauth-pgp-login.yaml +0 -0
  174. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/claims_mapper.py +0 -0
  175. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/nonce_store.py +0 -0
  176. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/stage.py +0 -0
  177. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/urls.py +0 -0
  178. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authentik/verifier.py +0 -0
  179. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/authz.py +0 -0
  180. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/cli.py +0 -0
  181. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/control_plane.py +0 -0
  182. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/control_plane_authorizer.py +0 -0
  183. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/control_plane_session.py +0 -0
  184. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/__init__.py +0 -0
  185. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/base.py +0 -0
  186. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/gnupg_backend.py +0 -0
  187. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/pgpy_backend.py +0 -0
  188. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/sequoia_backend.py +0 -0
  189. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/crypto/skpgp_backend.py +0 -0
  190. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/custody.py +0 -0
  191. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/delegated.py +0 -0
  192. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/did.py +0 -0
  193. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/__init__.py +0 -0
  194. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/base.py +0 -0
  195. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/file_discovery.py +0 -0
  196. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/mdns.py +0 -0
  197. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/discovery/syncthing.py +0 -0
  198. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/estate.py +0 -0
  199. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/exceptions.py +0 -0
  200. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/identity.py +0 -0
  201. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/identity_class.py +0 -0
  202. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/__init__.py +0 -0
  203. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/__init__.py +0 -0
  204. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/auth_flow.py +0 -0
  205. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/cli.py +0 -0
  206. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/config.py +0 -0
  207. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/forgejo_api.py +0 -0
  208. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/oidc_provider.py +0 -0
  209. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/__init__.py +0 -0
  210. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_auth_flow.py +0 -0
  211. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_cli.py +0 -0
  212. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_config.py +0 -0
  213. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_forgejo_api.py +0 -0
  214. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/forgejo/tests/test_oidc_provider.py +0 -0
  215. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/.gitignore +0 -0
  216. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/.nextcloudignore +0 -0
  217. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/CSR-PR.md +0 -0
  218. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/INFO-XML-CHANGES.md +0 -0
  219. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/PUBLISHING.md +0 -0
  220. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/README.md +0 -0
  221. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/appinfo/info.xml +0 -0
  222. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/appinfo/routes.php +0 -0
  223. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/build-release.sh +0 -0
  224. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/certificates/.gitignore +0 -0
  225. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/certificates/capauth.crt +0 -0
  226. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/certificates/capauth.csr +0 -0
  227. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/composer.json +0 -0
  228. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/css/login.css +0 -0
  229. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/js/login.js +0 -0
  230. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/krankerl.toml +0 -0
  231. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/AlternativeLogin/CapAuthLogin.php +0 -0
  232. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/AppInfo/Application.php +0 -0
  233. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/BackgroundJob/PruneExpiredNonces.php +0 -0
  234. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Controller/LoginController.php +0 -0
  235. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Controller/TokenController.php +0 -0
  236. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Db/KeyRegistry.php +0 -0
  237. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Exception/CapAuthUnauthorizedException.php +0 -0
  238. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Middleware/PgpVerificationMiddleware.php +0 -0
  239. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Migration/Version000300Date20260301000000.php +0 -0
  240. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Provider/CapAuthProvider.php +0 -0
  241. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/ChallengeService.php +0 -0
  242. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/GroupSyncService.php +0 -0
  243. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/UserProvisioningService.php +0 -0
  244. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/Service/VerifierService.php +0 -0
  245. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/lib/User/Backend.php +0 -0
  246. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/phpunit.xml +0 -0
  247. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/screenshots/README.md +0 -0
  248. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/screenshots/login.png +0 -0
  249. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/templates/login.php +0 -0
  250. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/bootstrap.php +0 -0
  251. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/integration/FullAuthFlowTest.php +0 -0
  252. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/oidc/oidc_e2e_login_test.py +0 -0
  253. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Controller/LoginControllerTest.php +0 -0
  254. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Db/KeyRegistryTest.php +0 -0
  255. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Provider/CapAuthProviderTest.php +0 -0
  256. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Service/ChallengeServiceTest.php +0 -0
  257. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/Service/VerifierServiceTest.php +0 -0
  258. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/integrations/nextcloud/tests/unit/User/BackendTest.php +0 -0
  259. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/key_transparency.py +0 -0
  260. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/login.py +0 -0
  261. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/manifest.py +0 -0
  262. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/mesh.py +0 -0
  263. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/migrations/0001_initial.py +0 -0
  264. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/migrations/0002_widen_fingerprint_to_64.py +0 -0
  265. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/migrations/__init__.py +0 -0
  266. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/models.py +0 -0
  267. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/__init__.py +0 -0
  268. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/canonicalize.py +0 -0
  269. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/kernel.py +0 -0
  270. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/operator_session.py +0 -0
  271. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/proof.py +0 -0
  272. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/records.py +0 -0
  273. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/store.py +0 -0
  274. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pairing/window.py +0 -0
  275. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pma.py +0 -0
  276. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_confidentiality.py +0 -0
  277. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_identity.py +0 -0
  278. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_root_identity.py +0 -0
  279. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/pqc_tokens.py +0 -0
  280. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/profile.py +0 -0
  281. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/provisioning.py +0 -0
  282. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/registry.py +0 -0
  283. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/rotation.py +0 -0
  284. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/seal.py +0 -0
  285. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/__init__.py +0 -0
  286. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/app.py +0 -0
  287. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/bunker.py +0 -0
  288. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/bunker_e2e.py +0 -0
  289. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/keystore.py +0 -0
  290. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/__init__.py +0 -0
  291. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/clients.example.json +0 -0
  292. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/clients.py +0 -0
  293. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/passkey.py +0 -0
  294. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/signing_key.py +0 -0
  295. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/static/bunker/lib/bunker-e2e.js +0 -0
  296. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/static/bunker/lib/keyvault.js +0 -0
  297. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/static/bunker/vendor/openpgp.min.js +0 -0
  298. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/oidc/store.py +0 -0
  299. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/push.py +0 -0
  300. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/service/server.py +0 -0
  301. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/sign_challenge.py +0 -0
  302. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/subject.py +0 -0
  303. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/sync.py +0 -0
  304. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/testing.py +0 -0
  305. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/tokens.py +0 -0
  306. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/trust/__init__.py +0 -0
  307. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/trust/calibration.py +0 -0
  308. {capauth-0.3.13 → capauth-0.3.14}/src/capauth/trust/graph.py +0 -0
  309. {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/dependency_links.txt +0 -0
  310. {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/entry_points.txt +0 -0
  311. {capauth-0.3.13 → capauth-0.3.14}/src/capauth.egg-info/top_level.txt +0 -0
  312. {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/.gitignore +0 -0
  313. {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/package-lock.json +0 -0
  314. {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/package.json +0 -0
  315. {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/src/CapAuthStage.test.js +0 -0
  316. {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/src/CapAuthStage.vue +0 -0
  317. {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/src/index.js +0 -0
  318. {capauth-0.3.13 → capauth-0.3.14}/stages/ak-stage-capauth/vite.config.js +0 -0
  319. {capauth-0.3.13 → capauth-0.3.14}/tests/__init__.py +0 -0
  320. {capauth-0.3.13 → capauth-0.3.14}/tests/conftest.py +0 -0
  321. {capauth-0.3.13 → capauth-0.3.14}/tests/fixtures/bunker_e2e_v1_vector.json +0 -0
  322. {capauth-0.3.13 → capauth-0.3.14}/tests/fixtures/canonical_nonce_v2_vector.json +0 -0
  323. {capauth-0.3.13 → capauth-0.3.14}/tests/test_agent_identity.py +0 -0
  324. {capauth-0.3.13 → capauth-0.3.14}/tests/test_agentrun_capabilities.py +0 -0
  325. {capauth-0.3.13 → capauth-0.3.14}/tests/test_audience_mint_helper.py +0 -0
  326. {capauth-0.3.13 → capauth-0.3.14}/tests/test_audience_tokens.py +0 -0
  327. {capauth-0.3.13 → capauth-0.3.14}/tests/test_audience_ttl_seconds.py +0 -0
  328. {capauth-0.3.13 → capauth-0.3.14}/tests/test_authz.py +0 -0
  329. {capauth-0.3.13 → capauth-0.3.14}/tests/test_authz_legacy_grace.py +0 -0
  330. {capauth-0.3.13 → capauth-0.3.14}/tests/test_authz_signature_gate.py +0 -0
  331. {capauth-0.3.13 → capauth-0.3.14}/tests/test_backup_fallback.py +0 -0
  332. {capauth-0.3.13 → capauth-0.3.14}/tests/test_backup_restore.py +0 -0
  333. {capauth-0.3.13 → capauth-0.3.14}/tests/test_bunker.py +0 -0
  334. {capauth-0.3.13 → capauth-0.3.14}/tests/test_bunker_e2e.py +0 -0
  335. {capauth-0.3.13 → capauth-0.3.14}/tests/test_canonicalize.py +0 -0
  336. {capauth-0.3.13 → capauth-0.3.14}/tests/test_capauth_service_deploy.py +0 -0
  337. {capauth-0.3.13 → capauth-0.3.14}/tests/test_change_capabilities.py +0 -0
  338. {capauth-0.3.13 → capauth-0.3.14}/tests/test_claims_mapper.py +0 -0
  339. {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane.py +0 -0
  340. {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane_authorizer.py +0 -0
  341. {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane_capabilities.py +0 -0
  342. {capauth-0.3.13 → capauth-0.3.14}/tests/test_control_plane_session.py +0 -0
  343. {capauth-0.3.13 → capauth-0.3.14}/tests/test_crypto.py +0 -0
  344. {capauth-0.3.13 → capauth-0.3.14}/tests/test_custody.py +0 -0
  345. {capauth-0.3.13 → capauth-0.3.14}/tests/test_delegated_capabilities.py +0 -0
  346. {capauth-0.3.13 → capauth-0.3.14}/tests/test_device_key_proof.py +0 -0
  347. {capauth-0.3.13 → capauth-0.3.14}/tests/test_did_capability_relationships.py +0 -0
  348. {capauth-0.3.13 → capauth-0.3.14}/tests/test_dockerfile_version.py +0 -0
  349. {capauth-0.3.13 → capauth-0.3.14}/tests/test_enrollment_proof_helper.py +0 -0
  350. {capauth-0.3.13 → capauth-0.3.14}/tests/test_estate.py +0 -0
  351. {capauth-0.3.13 → capauth-0.3.14}/tests/test_fingerprint_v6.py +0 -0
  352. {capauth-0.3.13 → capauth-0.3.14}/tests/test_forgejo_preflight.py +0 -0
  353. {capauth-0.3.13 → capauth-0.3.14}/tests/test_home_resolution.py +0 -0
  354. {capauth-0.3.13 → capauth-0.3.14}/tests/test_identity.py +0 -0
  355. {capauth-0.3.13 → capauth-0.3.14}/tests/test_identity_class.py +0 -0
  356. {capauth-0.3.13 → capauth-0.3.14}/tests/test_identity_ttl.py +0 -0
  357. {capauth-0.3.13 → capauth-0.3.14}/tests/test_installed_bunker_assets.py +0 -0
  358. {capauth-0.3.13 → capauth-0.3.14}/tests/test_key_revocation_expiry.py +0 -0
  359. {capauth-0.3.13 → capauth-0.3.14}/tests/test_key_transparency.py +0 -0
  360. {capauth-0.3.13 → capauth-0.3.14}/tests/test_login.py +0 -0
  361. {capauth-0.3.13 → capauth-0.3.14}/tests/test_manifest.py +0 -0
  362. {capauth-0.3.13 → capauth-0.3.14}/tests/test_mesh.py +0 -0
  363. {capauth-0.3.13 → capauth-0.3.14}/tests/test_models_pqc_q0.py +0 -0
  364. {capauth-0.3.13 → capauth-0.3.14}/tests/test_nextcloud_app.py +0 -0
  365. {capauth-0.3.13 → capauth-0.3.14}/tests/test_no_subapp_dependency.py +0 -0
  366. {capauth-0.3.13 → capauth-0.3.14}/tests/test_nonce_store.py +0 -0
  367. {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_durable_store.py +0 -0
  368. {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_hardening.py +0 -0
  369. {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_idp.py +0 -0
  370. {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_idp_e2e.py +0 -0
  371. {capauth-0.3.13 → capauth-0.3.14}/tests/test_oidc_refresh_family.py +0 -0
  372. {capauth-0.3.13 → capauth-0.3.14}/tests/test_operator_session.py +0 -0
  373. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pairing.py +0 -0
  374. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pairing_base_dir_env.py +0 -0
  375. {capauth-0.3.13 → capauth-0.3.14}/tests/test_passkey.py +0 -0
  376. {capauth-0.3.13 → capauth-0.3.14}/tests/test_passkey_enrollment_ux.py +0 -0
  377. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pma.py +0 -0
  378. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_confidentiality.py +0 -0
  379. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_identity.py +0 -0
  380. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_root_integration.py +0 -0
  381. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_t3_gate.py +0 -0
  382. {capauth-0.3.13 → capauth-0.3.14}/tests/test_pqc_tokens.py +0 -0
  383. {capauth-0.3.13 → capauth-0.3.14}/tests/test_profile.py +0 -0
  384. {capauth-0.3.13 → capauth-0.3.14}/tests/test_provisioning.py +0 -0
  385. {capauth-0.3.13 → capauth-0.3.14}/tests/test_push.py +0 -0
  386. {capauth-0.3.13 → capauth-0.3.14}/tests/test_py313_compat.py +0 -0
  387. {capauth-0.3.13 → capauth-0.3.14}/tests/test_qr_login.py +0 -0
  388. {capauth-0.3.13 → capauth-0.3.14}/tests/test_real_pgp_e2e.py +0 -0
  389. {capauth-0.3.13 → capauth-0.3.14}/tests/test_register_cli.py +0 -0
  390. {capauth-0.3.13 → capauth-0.3.14}/tests/test_registry.py +0 -0
  391. {capauth-0.3.13 → capauth-0.3.14}/tests/test_rotation.py +0 -0
  392. {capauth-0.3.13 → capauth-0.3.14}/tests/test_seal.py +0 -0
  393. {capauth-0.3.13 → capauth-0.3.14}/tests/test_sequoia_backend.py +0 -0
  394. {capauth-0.3.13 → capauth-0.3.14}/tests/test_service.py +0 -0
  395. {capauth-0.3.13 → capauth-0.3.14}/tests/test_service_authz_decide.py +0 -0
  396. {capauth-0.3.13 → capauth-0.3.14}/tests/test_service_v6_fingerprint.py +0 -0
  397. {capauth-0.3.13 → capauth-0.3.14}/tests/test_sign_challenge.py +0 -0
  398. {capauth-0.3.13 → capauth-0.3.14}/tests/test_skpgp_backend.py +0 -0
  399. {capauth-0.3.13 → capauth-0.3.14}/tests/test_subject.py +0 -0
  400. {capauth-0.3.13 → capauth-0.3.14}/tests/test_sync.py +0 -0
  401. {capauth-0.3.13 → capauth-0.3.14}/tests/test_syncthing_discovery.py +0 -0
  402. {capauth-0.3.13 → capauth-0.3.14}/tests/test_testing_helper.py +0 -0
  403. {capauth-0.3.13 → capauth-0.3.14}/tests/test_token_gc.py +0 -0
  404. {capauth-0.3.13 → capauth-0.3.14}/tests/test_token_store_flag.py +0 -0
  405. {capauth-0.3.13 → capauth-0.3.14}/tests/test_tokens.py +0 -0
  406. {capauth-0.3.13 → capauth-0.3.14}/tests/test_trust_calibration.py +0 -0
  407. {capauth-0.3.13 → capauth-0.3.14}/tests/test_trust_graph.py +0 -0
  408. {capauth-0.3.13 → capauth-0.3.14}/tests/test_trust_graph_coord_audit.py +0 -0
  409. {capauth-0.3.13 → capauth-0.3.14}/tests/test_verifier.py +0 -0
  410. {capauth-0.3.13 → capauth-0.3.14}/tests/test_version_honesty.py +0 -0
  411. {capauth-0.3.13 → capauth-0.3.14}/tests/test_zk_profile.py +0 -0
  412. {capauth-0.3.13 → capauth-0.3.14}/tools/build-sq.sh +0 -0
  413. {capauth-0.3.13 → capauth-0.3.14}/web/README.md +0 -0
  414. {capauth-0.3.13 → capauth-0.3.14}/web/stages/capauth/CapAuthStage.ts +0 -0
@@ -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 ghcr.io/smilintux/authentik-capauth:2026.5.3 \
8
- # -t ghcr.io/smilintux/authentik-capauth:latest .
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 ghcr.io/smilintux/authentik-capauth:2026.5.3
12
- # docker push ghcr.io/smilintux/authentik-capauth:latest
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=2026.5.3
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.13
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.6; extra == "service"
41
- Requires-Dist: PyJWT>=2.8; extra == "service"
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.38; extra == "dev"
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:** Proposed (decision pending Chef)
4
- **Date:** 2026-06-22
5
- **Author:** Opus (research + recommendation)
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 — upstream PR, fork/custom image, redistributable package, or drop
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 — a custom Django app layered on the stock image with
15
- > NO web-bundle rebuild — and use Authentik's *existing* WebAuthn/passkey or an
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 — observed, not theoretical)
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 — a shared chunk defines Lit's
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–cap12 ship the
59
- stock frontend, so the `ak-stage-capauth` component is ABSENT — the PGP login
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 — but the core
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* — it can only
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** — and it is the
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 — useful for claims logic, but cannot render a custom login UI or
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 — and per BeryJu it is not a supported way to
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 — where the fingerprint *is* the user and
173
- the user table is a key registry — is a sovereign-identity philosophy that does
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 — that is far more upstream-friendly *and* removes our
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 — Upstream PR to Authentik core (the stage)
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 — best reach. |
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 — Maintain the custom image fork (current state)
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 — every bump. |
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 — Redistributable Authentik integration (no core fork)
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 — Backend-only custom Django app, stock frontend.** Ship the `capauth`
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 — CapAuth as an OIDC/OAuth *Source* (recommended sub-flavor).** Run the
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 — no Authentik bundle), then
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 — Drop Authentik; native per-app CapAuth plugins
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** — the thing the Authentik fork can't currently do. |
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 — and it's publishable to the app's marketplace (Nextcloud app store), real reach. |
256
- | **Time cost** | One plugin per target app (Forgejo scaffold exists; others TBD). No central SSO — N integrations for N apps. |
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 — Option D
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–2 apps by actual need (Forgejo scaffold already exists).
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 — Option C2
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** — fully ours, zero Authentik web patching.
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 — eliminating the version-bump treadmill.
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 — there is no
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 — slashing
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):** approve the two-track strategy; mark the
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 (spike):** add OIDC provider endpoints to the standalone CapAuth
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 — "merge upstream, or use the API":
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 — the C2 path):
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 — ongoing passkey investment):
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.6",
49
- "PyJWT>=2.8",
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.38",
65
+ "zeroconf>=0.149.16",
66
66
  "webauthn>=2.0",
67
67
  "soft-webauthn>=0.1",
68
68
  "pywebpush>=1.14",