acr-control-plane 1.1.3__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 (195) hide show
  1. acr_control_plane-1.1.3/.env.example +123 -0
  2. acr_control_plane-1.1.3/.env.production.example +64 -0
  3. acr_control_plane-1.1.3/.github/workflows/ci.yml +180 -0
  4. acr_control_plane-1.1.3/.github/workflows/release.yml +76 -0
  5. acr_control_plane-1.1.3/.github/workflows/security.yml +126 -0
  6. acr_control_plane-1.1.3/.gitignore +28 -0
  7. acr_control_plane-1.1.3/Dockerfile +40 -0
  8. acr_control_plane-1.1.3/Dockerfile.killswitch +33 -0
  9. acr_control_plane-1.1.3/LICENSE +111 -0
  10. acr_control_plane-1.1.3/PKG-INFO +378 -0
  11. acr_control_plane-1.1.3/README.md +334 -0
  12. acr_control_plane-1.1.3/alembic.ini +39 -0
  13. acr_control_plane-1.1.3/deploy/k8s/base/gateway-configmap.yaml +37 -0
  14. acr_control_plane-1.1.3/deploy/k8s/base/gateway-deployment.yaml +107 -0
  15. acr_control_plane-1.1.3/deploy/k8s/base/gateway-secret.example.yaml +21 -0
  16. acr_control_plane-1.1.3/deploy/k8s/base/gateway-service.yaml +10 -0
  17. acr_control_plane-1.1.3/deploy/k8s/base/hpas.yaml +77 -0
  18. acr_control_plane-1.1.3/deploy/k8s/base/ingress.yaml +39 -0
  19. acr_control_plane-1.1.3/deploy/k8s/base/killswitch-deployment.yaml +89 -0
  20. acr_control_plane-1.1.3/deploy/k8s/base/killswitch-service.yaml +10 -0
  21. acr_control_plane-1.1.3/deploy/k8s/base/kustomization.yaml +17 -0
  22. acr_control_plane-1.1.3/deploy/k8s/base/namespace.yaml +4 -0
  23. acr_control_plane-1.1.3/deploy/k8s/base/networkpolicy.yaml +149 -0
  24. acr_control_plane-1.1.3/deploy/k8s/base/opa-deployment.yaml +70 -0
  25. acr_control_plane-1.1.3/deploy/k8s/base/opa-service.yaml +10 -0
  26. acr_control_plane-1.1.3/deploy/k8s/base/pdbs.yaml +32 -0
  27. acr_control_plane-1.1.3/deploy/k8s/base/rbac.yaml +33 -0
  28. acr_control_plane-1.1.3/deploy/k8s/overlays/production/README.md +84 -0
  29. acr_control_plane-1.1.3/deploy/k8s/overlays/production/external-secret.yaml +83 -0
  30. acr_control_plane-1.1.3/deploy/k8s/overlays/production/gateway-configmap-patch.yaml +34 -0
  31. acr_control_plane-1.1.3/deploy/k8s/overlays/production/gateway-deployment-patch.yaml +24 -0
  32. acr_control_plane-1.1.3/deploy/k8s/overlays/production/ingress-patch.yaml +27 -0
  33. acr_control_plane-1.1.3/deploy/k8s/overlays/production/killswitch-deployment-patch.yaml +24 -0
  34. acr_control_plane-1.1.3/deploy/k8s/overlays/production/kustomization.yaml +25 -0
  35. acr_control_plane-1.1.3/deploy/k8s/overlays/production/namespace-patch.yaml +9 -0
  36. acr_control_plane-1.1.3/deploy/k8s/overlays/production/networkpolicy-production.yaml +127 -0
  37. acr_control_plane-1.1.3/deploy/k8s/overlays/production/opa-deployment-patch.yaml +24 -0
  38. acr_control_plane-1.1.3/deploy/k8s/overlays/production/remove-base-gateway-netpol.yaml +6 -0
  39. acr_control_plane-1.1.3/deploy/k8s/overlays/production/remove-base-killswitch-netpol.yaml +6 -0
  40. acr_control_plane-1.1.3/docker-compose.yml +190 -0
  41. acr_control_plane-1.1.3/docs/api.md +511 -0
  42. acr_control_plane-1.1.3/docs/compliance/README.md +56 -0
  43. acr_control_plane-1.1.3/docs/compliance/control-mapping.md +58 -0
  44. acr_control_plane-1.1.3/docs/compliance/evidence-package.md +56 -0
  45. acr_control_plane-1.1.3/docs/compliance/external-assessment-scope.md +56 -0
  46. acr_control_plane-1.1.3/docs/compliance/shared-responsibility-matrix.md +27 -0
  47. acr_control_plane-1.1.3/docs/compliance/threat-model.md +150 -0
  48. acr_control_plane-1.1.3/docs/configuration.md +100 -0
  49. acr_control_plane-1.1.3/docs/deployment.md +170 -0
  50. acr_control_plane-1.1.3/docs/enterprise-roadmap.md +186 -0
  51. acr_control_plane-1.1.3/docs/failure-load-dr-validation-2026-04-08.md +230 -0
  52. acr_control_plane-1.1.3/docs/orchestrators.md +145 -0
  53. acr_control_plane-1.1.3/docs/production_install.md +171 -0
  54. acr_control_plane-1.1.3/docs/provenance-and-verification.md +98 -0
  55. acr_control_plane-1.1.3/docs/sdk.md +113 -0
  56. acr_control_plane-1.1.3/examples/n8n/README.md +95 -0
  57. acr_control_plane-1.1.3/examples/n8n/acr_sensitive_action_workflow.json +254 -0
  58. acr_control_plane-1.1.3/examples/protected_executor/.env.example +3 -0
  59. acr_control_plane-1.1.3/examples/protected_executor/Dockerfile +17 -0
  60. acr_control_plane-1.1.3/examples/protected_executor/README.md +96 -0
  61. acr_control_plane-1.1.3/examples/protected_executor/app.py +84 -0
  62. acr_control_plane-1.1.3/examples/sample_agent/README.md +55 -0
  63. acr_control_plane-1.1.3/examples/sample_agent/agent.py +146 -0
  64. acr_control_plane-1.1.3/examples/sample_agent/tools.py +38 -0
  65. acr_control_plane-1.1.3/policies/acr/common.rego +86 -0
  66. acr_control_plane-1.1.3/policies/acr/customer_support.rego +53 -0
  67. acr_control_plane-1.1.3/pyproject.toml +126 -0
  68. acr_control_plane-1.1.3/scripts/build_compliance_package.py +171 -0
  69. acr_control_plane-1.1.3/scripts/check_no_dev_secrets.py +53 -0
  70. acr_control_plane-1.1.3/scripts/generate_secrets.py +72 -0
  71. acr_control_plane-1.1.3/scripts/run-migrations.sh +36 -0
  72. acr_control_plane-1.1.3/sdks/typescript/README.md +69 -0
  73. acr_control_plane-1.1.3/sdks/typescript/dist/index.d.ts +129 -0
  74. acr_control_plane-1.1.3/sdks/typescript/dist/index.js +197 -0
  75. acr_control_plane-1.1.3/sdks/typescript/package.json +26 -0
  76. acr_control_plane-1.1.3/sdks/typescript/src/index.ts +323 -0
  77. acr_control_plane-1.1.3/sdks/typescript/tsconfig.json +14 -0
  78. acr_control_plane-1.1.3/src/acr/__init__.py +8 -0
  79. acr_control_plane-1.1.3/src/acr/auth/router.py +96 -0
  80. acr_control_plane-1.1.3/src/acr/common/__init__.py +0 -0
  81. acr_control_plane-1.1.3/src/acr/common/correlation.py +24 -0
  82. acr_control_plane-1.1.3/src/acr/common/errors.py +165 -0
  83. acr_control_plane-1.1.3/src/acr/common/oidc.py +160 -0
  84. acr_control_plane-1.1.3/src/acr/common/operator_auth.py +97 -0
  85. acr_control_plane-1.1.3/src/acr/common/redis_client.py +45 -0
  86. acr_control_plane-1.1.3/src/acr/common/time.py +13 -0
  87. acr_control_plane-1.1.3/src/acr/config.py +283 -0
  88. acr_control_plane-1.1.3/src/acr/db/__init__.py +0 -0
  89. acr_control_plane-1.1.3/src/acr/db/database.py +59 -0
  90. acr_control_plane-1.1.3/src/acr/db/migrations/env.py +68 -0
  91. acr_control_plane-1.1.3/src/acr/db/migrations/script.py.mako +28 -0
  92. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0001_initial.py +146 -0
  93. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0002_cascade_fks_and_indexes.py +113 -0
  94. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0003_status_check_constraints.py +66 -0
  95. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0004_approval_execution_result.py +27 -0
  96. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0005_operator_credentials.py +42 -0
  97. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0006_policy_drafts.py +40 -0
  98. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0007_policy_releases.py +49 -0
  99. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0008_policy_release_artifacts.py +27 -0
  100. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0009_policy_release_activation.py +35 -0
  101. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0010_drift_baseline_versions.py +71 -0
  102. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0011_monthly_partitioning.py +147 -0
  103. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0012_agent_registry_expansion.py +104 -0
  104. acr_control_plane-1.1.3/src/acr/db/migrations/versions/0013_policy_decision_modify.py +33 -0
  105. acr_control_plane-1.1.3/src/acr/db/models.py +338 -0
  106. acr_control_plane-1.1.3/src/acr/gateway/__init__.py +0 -0
  107. acr_control_plane-1.1.3/src/acr/gateway/auth.py +33 -0
  108. acr_control_plane-1.1.3/src/acr/gateway/executor.py +125 -0
  109. acr_control_plane-1.1.3/src/acr/gateway/executor_auth.py +265 -0
  110. acr_control_plane-1.1.3/src/acr/gateway/executor_integrations.py +184 -0
  111. acr_control_plane-1.1.3/src/acr/gateway/middleware.py +46 -0
  112. acr_control_plane-1.1.3/src/acr/gateway/models.py +63 -0
  113. acr_control_plane-1.1.3/src/acr/gateway/proxy.py +36 -0
  114. acr_control_plane-1.1.3/src/acr/gateway/router.py +736 -0
  115. acr_control_plane-1.1.3/src/acr/gateway/spend_control.py +96 -0
  116. acr_control_plane-1.1.3/src/acr/main.py +715 -0
  117. acr_control_plane-1.1.3/src/acr/operator_console/__init__.py +1 -0
  118. acr_control_plane-1.1.3/src/acr/operator_console/router.py +35 -0
  119. acr_control_plane-1.1.3/src/acr/operator_console/static/app.js +909 -0
  120. acr_control_plane-1.1.3/src/acr/operator_console/static/index.html +510 -0
  121. acr_control_plane-1.1.3/src/acr/operator_console/static/styles.css +348 -0
  122. acr_control_plane-1.1.3/src/acr/operator_keys/__init__.py +1 -0
  123. acr_control_plane-1.1.3/src/acr/operator_keys/models.py +34 -0
  124. acr_control_plane-1.1.3/src/acr/operator_keys/router.py +62 -0
  125. acr_control_plane-1.1.3/src/acr/operator_keys/service.py +111 -0
  126. acr_control_plane-1.1.3/src/acr/pillar1_identity/__init__.py +0 -0
  127. acr_control_plane-1.1.3/src/acr/pillar1_identity/models.py +171 -0
  128. acr_control_plane-1.1.3/src/acr/pillar1_identity/registry.py +322 -0
  129. acr_control_plane-1.1.3/src/acr/pillar1_identity/router.py +233 -0
  130. acr_control_plane-1.1.3/src/acr/pillar1_identity/validator.py +94 -0
  131. acr_control_plane-1.1.3/src/acr/pillar2_policy/__init__.py +0 -0
  132. acr_control_plane-1.1.3/src/acr/pillar2_policy/engine.py +246 -0
  133. acr_control_plane-1.1.3/src/acr/pillar2_policy/models.py +38 -0
  134. acr_control_plane-1.1.3/src/acr/pillar2_policy/output_filter.py +106 -0
  135. acr_control_plane-1.1.3/src/acr/pillar3_drift/__init__.py +0 -0
  136. acr_control_plane-1.1.3/src/acr/pillar3_drift/baseline.py +155 -0
  137. acr_control_plane-1.1.3/src/acr/pillar3_drift/detector.py +158 -0
  138. acr_control_plane-1.1.3/src/acr/pillar3_drift/governance.py +177 -0
  139. acr_control_plane-1.1.3/src/acr/pillar3_drift/models.py +70 -0
  140. acr_control_plane-1.1.3/src/acr/pillar3_drift/signals.py +90 -0
  141. acr_control_plane-1.1.3/src/acr/pillar4_observability/__init__.py +0 -0
  142. acr_control_plane-1.1.3/src/acr/pillar4_observability/evidence.py +94 -0
  143. acr_control_plane-1.1.3/src/acr/pillar4_observability/integrity.py +88 -0
  144. acr_control_plane-1.1.3/src/acr/pillar4_observability/otel.py +117 -0
  145. acr_control_plane-1.1.3/src/acr/pillar4_observability/schema.py +118 -0
  146. acr_control_plane-1.1.3/src/acr/pillar4_observability/telemetry.py +148 -0
  147. acr_control_plane-1.1.3/src/acr/pillar5_containment/__init__.py +0 -0
  148. acr_control_plane-1.1.3/src/acr/pillar5_containment/graduated.py +149 -0
  149. acr_control_plane-1.1.3/src/acr/pillar5_containment/killswitch.py +119 -0
  150. acr_control_plane-1.1.3/src/acr/pillar5_containment/models.py +54 -0
  151. acr_control_plane-1.1.3/src/acr/pillar5_containment/router.py +53 -0
  152. acr_control_plane-1.1.3/src/acr/pillar5_containment/service.py +208 -0
  153. acr_control_plane-1.1.3/src/acr/pillar6_authority/__init__.py +0 -0
  154. acr_control_plane-1.1.3/src/acr/pillar6_authority/approval.py +247 -0
  155. acr_control_plane-1.1.3/src/acr/pillar6_authority/models.py +52 -0
  156. acr_control_plane-1.1.3/src/acr/pillar6_authority/router.py +101 -0
  157. acr_control_plane-1.1.3/src/acr/pillar6_authority/tiering.py +55 -0
  158. acr_control_plane-1.1.3/src/acr/policy_studio/__init__.py +1 -0
  159. acr_control_plane-1.1.3/src/acr/policy_studio/bundles.py +54 -0
  160. acr_control_plane-1.1.3/src/acr/policy_studio/distribution.py +102 -0
  161. acr_control_plane-1.1.3/src/acr/policy_studio/models.py +84 -0
  162. acr_control_plane-1.1.3/src/acr/policy_studio/publisher.py +192 -0
  163. acr_control_plane-1.1.3/src/acr/policy_studio/releases.py +198 -0
  164. acr_control_plane-1.1.3/src/acr/policy_studio/router.py +223 -0
  165. acr_control_plane-1.1.3/src/acr/policy_studio/service.py +70 -0
  166. acr_control_plane-1.1.3/src/acr/policy_studio/simulator.py +109 -0
  167. acr_control_plane-1.1.3/src/acr/sdk/__init__.py +35 -0
  168. acr_control_plane-1.1.3/src/acr/sdk/client.py +405 -0
  169. acr_control_plane-1.1.3/src/acr/sdk/errors.py +34 -0
  170. acr_control_plane-1.1.3/src/acr/sdk/langgraph.py +173 -0
  171. acr_control_plane-1.1.3/tests/conftest.py +129 -0
  172. acr_control_plane-1.1.3/tests/integration/__init__.py +0 -0
  173. acr_control_plane-1.1.3/tests/integration/conftest.py +114 -0
  174. acr_control_plane-1.1.3/tests/integration/test_integration.py +165 -0
  175. acr_control_plane-1.1.3/tests/test_authority.py +182 -0
  176. acr_control_plane-1.1.3/tests/test_authority_advanced.py +294 -0
  177. acr_control_plane-1.1.3/tests/test_concurrency.py +205 -0
  178. acr_control_plane-1.1.3/tests/test_containment.py +40 -0
  179. acr_control_plane-1.1.3/tests/test_drift.py +80 -0
  180. acr_control_plane-1.1.3/tests/test_drift_db.py +413 -0
  181. acr_control_plane-1.1.3/tests/test_drift_governance_api.py +90 -0
  182. acr_control_plane-1.1.3/tests/test_enterprise_hardening.py +228 -0
  183. acr_control_plane-1.1.3/tests/test_evidence.py +75 -0
  184. acr_control_plane-1.1.3/tests/test_executor.py +232 -0
  185. acr_control_plane-1.1.3/tests/test_gateway.py +321 -0
  186. acr_control_plane-1.1.3/tests/test_identity.py +380 -0
  187. acr_control_plane-1.1.3/tests/test_killswitch_service.py +198 -0
  188. acr_control_plane-1.1.3/tests/test_observability.py +122 -0
  189. acr_control_plane-1.1.3/tests/test_operator_keys.py +155 -0
  190. acr_control_plane-1.1.3/tests/test_policy.py +37 -0
  191. acr_control_plane-1.1.3/tests/test_policy_engine.py +235 -0
  192. acr_control_plane-1.1.3/tests/test_policy_studio.py +309 -0
  193. acr_control_plane-1.1.3/tests/test_sdk.py +185 -0
  194. acr_control_plane-1.1.3/tests/test_secret_hygiene.py +32 -0
  195. acr_control_plane-1.1.3/tests/test_security_and_policy_services.py +343 -0
@@ -0,0 +1,123 @@
1
+ # ACR Control Plane — Environment Variable Template
2
+ #
3
+ # HOW TO USE:
4
+ # Development : cp .env.example .env (defaults work for local docker-compose)
5
+ # Staging/Prod: populate each CHANGE_ME value with a strong random secret.
6
+ # Use a secrets manager (Vault, AWS SM, K8s Secrets) — never
7
+ # commit real credentials to version control.
8
+ #
9
+ # Generate strong secrets with:
10
+ # python -c "import secrets; print(secrets.token_hex(32))"
11
+
12
+ # ── Database ──────────────────────────────────────────────────────────────────
13
+ # Format: postgresql+asyncpg://<user>:<password>@<host>:<port>/<db>
14
+ DATABASE_URL=postgresql+asyncpg://acr:acr_dev_password@localhost:5432/acr_control_plane
15
+
16
+ # Postgres service credentials (used by docker-compose postgres healthcheck)
17
+ POSTGRES_USER=acr
18
+ POSTGRES_PASSWORD=acr_dev_password
19
+ POSTGRES_DB=acr_control_plane
20
+
21
+ # ── Redis ─────────────────────────────────────────────────────────────────────
22
+ REDIS_URL=redis://localhost:6379/0
23
+
24
+ # ── Open Policy Agent ─────────────────────────────────────────────────────────
25
+ OPA_URL=http://localhost:8181
26
+
27
+ # ── Kill Switch ───────────────────────────────────────────────────────────────
28
+ KILLSWITCH_URL=http://localhost:8443
29
+ # Minimum 32 random bytes (hex). Required on ALL kill switch endpoints.
30
+ # Dev default is rejected in staging/production at startup.
31
+ KILLSWITCH_SECRET=killswitch_dev_secret_change_me
32
+
33
+ # ── JWT Authentication ────────────────────────────────────────────────────────
34
+ # HS256 requires >= 256-bit (32-byte) key.
35
+ # The server will refuse to start in non-development environments if this
36
+ # is set to a known-weak value or fewer than 32 bytes.
37
+ JWT_SECRET_KEY=dev_jwt_secret_change_in_production
38
+ JWT_ALGORITHM=HS256
39
+ JWT_TOKEN_EXPIRE_MINUTES=30
40
+
41
+ # ── Runtime ───────────────────────────────────────────────────────────────────
42
+ # Accepted values: development | staging | production
43
+ # Non-development environments enforce strong secret validation at startup.
44
+ ACR_ENV=development
45
+ LOG_LEVEL=INFO
46
+ ACR_VERSION=1.0
47
+ SCHEMA_BOOTSTRAP_MODE=auto
48
+ STRICT_DEPENDENCY_STARTUP=false
49
+
50
+ # ── Operator Auth / RBAC ─────────────────────────────────────────────────────
51
+ # JSON object keyed by API key. Each value must include a subject and roles.
52
+ # Example:
53
+ # OPERATOR_API_KEYS_JSON={"change-me":{"subject":"platform-admin","roles":["agent_admin","approver","security_admin","auditor","killswitch_operator"]}}
54
+ OPERATOR_API_KEYS_JSON=
55
+ # Used by the main gateway when it calls the independent kill switch service.
56
+ SERVICE_OPERATOR_API_KEY=
57
+ OPERATOR_SESSION_SECRET=dev_operator_session_secret_change_me
58
+ OIDC_ENABLED=false
59
+ OIDC_ISSUER=
60
+ OIDC_CLIENT_ID=
61
+ OIDC_CLIENT_SECRET=
62
+ OIDC_AUTHORIZE_URL=
63
+ OIDC_TOKEN_URL=
64
+ OIDC_JWKS_URL=
65
+ OIDC_REDIRECT_URI=
66
+ OIDC_SCOPES=openid profile email groups
67
+ OIDC_ROLES_CLAIM=groups
68
+ OIDC_SUBJECT_CLAIM=email
69
+ OIDC_ROLE_MAPPING_JSON=
70
+ OIDC_SESSION_TTL_SECONDS=28800
71
+
72
+ # ── Approval Webhook ─────────────────────────────────────────────────────────
73
+ # Leave blank to disable outbound webhook notifications.
74
+ WEBHOOK_URL=
75
+ # If set, each webhook POST carries X-ACR-Signature: <hmac-sha256-hex>.
76
+ # Receivers must verify this header before trusting the payload.
77
+ # Minimum 32 random bytes (hex). Leave blank to skip signing.
78
+ WEBHOOK_HMAC_SECRET=
79
+ # Minimum 32 random bytes (hex). Used to sign audit/evidence bundles.
80
+ AUDIT_SIGNING_SECRET=dev_audit_signing_secret_change_me
81
+
82
+ # ── OpenTelemetry ─────────────────────────────────────────────────────────────
83
+ # Leave blank to disable OTLP trace export (e.g. http://localhost:4318).
84
+ OTEL_EXPORTER_OTLP_ENDPOINT=
85
+ OTEL_SERVICE_NAME=acr-control-plane
86
+
87
+ # ── Downstream Execution ─────────────────────────────────────────────────────
88
+ # If true, allowed actions and approved escalations will POST to the configured tool executor URL.
89
+ EXECUTE_ALLOWED_ACTIONS=false
90
+ # Example: {"query_customer_db":"https://executor.internal/query-customer","issue_refund":"https://executor.internal/refund"}
91
+ TOOL_EXECUTOR_MAP_JSON=
92
+ # Structured integrations for common live business actions.
93
+ # Supported providers: refund_api, email_api, ticket_api, http
94
+ # Secret values can be referenced with env:NAME
95
+ EXECUTOR_INTEGRATIONS_JSON=
96
+ # Optional HMAC secret used to sign execution payloads with X-ACR-Execution-Signature.
97
+ EXECUTOR_HMAC_SECRET=
98
+ # Short-lived execution authorization TTL. Downstream executors should verify
99
+ # X-ACR-Execution-Token so actions cannot bypass the control plane.
100
+ EXECUTOR_AUTH_TTL_SECONDS=60
101
+ # Optional secret used to mint short-lived brokered downstream credentials.
102
+ # Downstream services can verify X-ACR-Brokered-Credential for audience/scope.
103
+ EXECUTOR_CREDENTIAL_SECRET=
104
+ EXECUTOR_CREDENTIAL_TTL_SECONDS=300
105
+ EXECUTOR_TIMEOUT_SECONDS=8.0
106
+
107
+ # ── Policy Bundle Publishing ────────────────────────────────────────────────
108
+ # Supported backends:
109
+ # local : write bundles to the local filesystem
110
+ # s3 : write bundles to S3 or an S3-compatible object store
111
+ REQUIRE_BUNDLE_AUTH=true
112
+ POLICY_BUNDLE_BACKEND=local
113
+ POLICY_BUNDLE_LOCAL_DIR=./var/policy_bundles
114
+ # Required when POLICY_BUNDLE_BACKEND=s3
115
+ POLICY_BUNDLE_S3_BUCKET=
116
+ # Optional key prefix inside the bucket
117
+ POLICY_BUNDLE_S3_PREFIX=acr/policy-bundles
118
+ # Optional AWS region / S3-compatible region hint
119
+ POLICY_BUNDLE_S3_REGION=
120
+ # Optional S3-compatible endpoint URL (e.g. MinIO, R2, Ceph)
121
+ POLICY_BUNDLE_S3_ENDPOINT_URL=
122
+ # Optional public/base URL shown in release history instead of a filesystem path.
123
+ POLICY_BUNDLE_PUBLIC_BASE_URL=
@@ -0,0 +1,64 @@
1
+ # ACR Control Plane — Production Environment Template
2
+ #
3
+ # Populate these values from a secret manager or generated output from:
4
+ # python scripts/generate_secrets.py > .env.production
5
+ #
6
+ # Do not commit real production values.
7
+
8
+ DATABASE_URL=postgresql+asyncpg://acr:${POSTGRES_PASSWORD}@db.example.internal:5432/acr_control_plane
9
+ REDIS_URL=redis://redis.example.internal:6379/0
10
+ OPA_URL=http://opa.example.internal:8181
11
+ KILLSWITCH_URL=http://acr-killswitch.example.internal:8443
12
+
13
+ POSTGRES_USER=acr
14
+ POSTGRES_PASSWORD=CHANGE_ME
15
+ POSTGRES_DB=acr_control_plane
16
+
17
+ JWT_SECRET_KEY=CHANGE_ME
18
+ JWT_ALGORITHM=HS256
19
+ JWT_TOKEN_EXPIRE_MINUTES=30
20
+
21
+ KILLSWITCH_SECRET=CHANGE_ME
22
+ AUDIT_SIGNING_SECRET=CHANGE_ME
23
+ OPERATOR_SESSION_SECRET=CHANGE_ME
24
+ WEBHOOK_HMAC_SECRET=CHANGE_ME
25
+ EXECUTOR_HMAC_SECRET=CHANGE_ME
26
+ EXECUTOR_CREDENTIAL_SECRET=CHANGE_ME
27
+ EXECUTOR_AUTH_TTL_SECONDS=60
28
+ EXECUTOR_CREDENTIAL_TTL_SECONDS=300
29
+
30
+ ACR_ENV=production
31
+ LOG_LEVEL=INFO
32
+ SCHEMA_BOOTSTRAP_MODE=validate
33
+ STRICT_DEPENDENCY_STARTUP=true
34
+
35
+ OPERATOR_API_KEYS_JSON=CHANGE_ME
36
+ SERVICE_OPERATOR_API_KEY=CHANGE_ME
37
+
38
+ OIDC_ENABLED=true
39
+ OIDC_ISSUER=https://idp.example.com
40
+ OIDC_CLIENT_ID=CHANGE_ME
41
+ OIDC_CLIENT_SECRET=CHANGE_ME
42
+ OIDC_AUTHORIZE_URL=https://idp.example.com/oauth2/authorize
43
+ OIDC_TOKEN_URL=https://idp.example.com/oauth2/token
44
+ OIDC_JWKS_URL=https://idp.example.com/.well-known/jwks.json
45
+ OIDC_REDIRECT_URI=https://acr.example.com/acr/auth/oidc/callback
46
+ OIDC_SCOPES=openid profile email groups
47
+ OIDC_ROLES_CLAIM=groups
48
+ OIDC_SUBJECT_CLAIM=email
49
+ OIDC_ROLE_MAPPING_JSON={"acr-platform-admin":["agent_admin","approver","security_admin","auditor","killswitch_operator"]}
50
+
51
+ EXECUTE_ALLOWED_ACTIONS=true
52
+ TOOL_EXECUTOR_MAP_JSON=CHANGE_ME
53
+ EXECUTOR_INTEGRATIONS_JSON=
54
+
55
+ WEBHOOK_URL=
56
+ OTEL_EXPORTER_OTLP_ENDPOINT=
57
+
58
+ REQUIRE_BUNDLE_AUTH=false
59
+ POLICY_BUNDLE_BACKEND=s3
60
+ POLICY_BUNDLE_S3_BUCKET=CHANGE_ME
61
+ POLICY_BUNDLE_S3_PREFIX=acr/policy-bundles
62
+ POLICY_BUNDLE_S3_REGION=us-east-1
63
+ POLICY_BUNDLE_S3_ENDPOINT_URL=
64
+ POLICY_BUNDLE_PUBLIC_BASE_URL=https://acr.example.com
@@ -0,0 +1,180 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main", "develop"]
6
+ pull_request:
7
+ branches: ["main"]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ # ── Lint ────────────────────────────────────────────────────────────────────
15
+ lint:
16
+ name: Lint
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.11"
24
+ cache: pip
25
+
26
+ - name: Install dev dependencies
27
+ run: pip install -e ".[dev]" ruff
28
+
29
+ - name: Ruff — format check
30
+ run: ruff format --check src/ tests/
31
+
32
+ - name: Ruff — lint
33
+ run: ruff check src/ tests/
34
+
35
+ # ── Tests ───────────────────────────────────────────────────────────────────
36
+ test:
37
+ name: Tests (Python ${{ matrix.python-version }})
38
+ runs-on: ubuntu-latest
39
+ strategy:
40
+ fail-fast: false
41
+ matrix:
42
+ python-version: ["3.11", "3.12"]
43
+
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+
47
+ - uses: actions/setup-python@v5
48
+ with:
49
+ python-version: ${{ matrix.python-version }}
50
+ cache: pip
51
+
52
+ - name: Install dependencies
53
+ run: pip install -e ".[dev]"
54
+
55
+ - name: Run tests with coverage
56
+ env:
57
+ # Use safe test defaults — no real secrets needed in CI
58
+ JWT_SECRET_KEY: "ci_test_secret_not_for_production_at_all"
59
+ KILLSWITCH_SECRET: "ci_killswitch_secret_not_for_production"
60
+ ACR_ENV: "test"
61
+ run: |
62
+ pytest tests/ -v \
63
+ --ignore=tests/integration \
64
+ --cov=src/acr \
65
+ --cov-report=term-missing \
66
+ --cov-report=xml \
67
+ --cov-fail-under=80
68
+
69
+ - name: Upload coverage report
70
+ if: matrix.python-version == '3.11'
71
+ uses: actions/upload-artifact@v4
72
+ with:
73
+ name: coverage-report
74
+ path: coverage.xml
75
+ retention-days: 7
76
+
77
+ # ── Integration Tests ──────────────────────────────────────────────────────
78
+ integration-tests:
79
+ name: Integration Tests
80
+ runs-on: ubuntu-latest
81
+ needs: [test]
82
+ steps:
83
+ - uses: actions/checkout@v4
84
+
85
+ - name: Start services
86
+ run: docker-compose up -d postgres redis opa
87
+ working-directory: implementations/acr-control-plane
88
+
89
+ - name: Wait for services
90
+ run: |
91
+ timeout 60 bash -c 'until docker-compose exec -T postgres pg_isready; do sleep 2; done'
92
+ timeout 30 bash -c 'until curl -sf http://localhost:8181/health; do sleep 2; done'
93
+ working-directory: implementations/acr-control-plane
94
+
95
+ - name: Set up Python
96
+ uses: actions/setup-python@v5
97
+ with:
98
+ python-version: "3.12"
99
+
100
+ - name: Install dependencies
101
+ run: pip install -e ".[dev]"
102
+ working-directory: implementations/acr-control-plane
103
+
104
+ - name: Run integration tests
105
+ run: pytest tests/integration/ -v --tb=short
106
+ working-directory: implementations/acr-control-plane
107
+ env:
108
+ RUN_INTEGRATION_TESTS: "true"
109
+ TEST_DATABASE_URL: postgresql+asyncpg://acr:acr_dev_password@localhost:5432/acr_control_plane
110
+ TEST_REDIS_URL: redis://localhost:6379/1
111
+ TEST_OPA_URL: http://localhost:8181
112
+
113
+ - name: Tear down services
114
+ if: always()
115
+ run: docker-compose down -v
116
+ working-directory: implementations/acr-control-plane
117
+
118
+ # ── Security ─────────────────────────────────────────────────────────────────
119
+ security:
120
+ name: Security scan (pip-audit)
121
+ runs-on: ubuntu-latest
122
+ steps:
123
+ - uses: actions/checkout@v4
124
+
125
+ - uses: actions/setup-python@v5
126
+ with:
127
+ python-version: "3.11"
128
+ cache: pip
129
+
130
+ - name: Install dependencies
131
+ run: pip install -e ".[dev]"
132
+
133
+ - name: pip-audit — check for known CVEs
134
+ run: pip-audit --strict
135
+
136
+ # ── OPA policy tests ─────────────────────────────────────────────────────────
137
+ opa:
138
+ name: OPA policy tests
139
+ runs-on: ubuntu-latest
140
+ steps:
141
+ - uses: actions/checkout@v4
142
+
143
+ - name: Install OPA
144
+ run: |
145
+ curl -L -o /usr/local/bin/opa \
146
+ https://openpolicyagent.org/downloads/v0.70.0/opa_linux_amd64_static
147
+ chmod +x /usr/local/bin/opa
148
+
149
+ - name: Verify OPA policies parse cleanly
150
+ run: opa check policies/
151
+
152
+ - name: Run OPA policy tests
153
+ run: opa test policies/ -v
154
+
155
+ # ── Docker build ─────────────────────────────────────────────────────────────
156
+ docker:
157
+ name: Docker build (${{ matrix.service }})
158
+ runs-on: ubuntu-latest
159
+ strategy:
160
+ matrix:
161
+ include:
162
+ - service: gateway
163
+ dockerfile: Dockerfile
164
+ - service: killswitch
165
+ dockerfile: Dockerfile.killswitch
166
+ steps:
167
+ - uses: actions/checkout@v4
168
+
169
+ - name: Set up Docker Buildx
170
+ uses: docker/setup-buildx-action@v3
171
+
172
+ - name: Build ${{ matrix.service }} image
173
+ uses: docker/build-push-action@v6
174
+ with:
175
+ context: .
176
+ file: ${{ matrix.dockerfile }}
177
+ push: false
178
+ cache-from: type=gha
179
+ cache-to: type=gha,mode=max
180
+ tags: acr-${{ matrix.service }}:ci
@@ -0,0 +1,76 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ permissions:
9
+ contents: read
10
+ packages: write
11
+
12
+ jobs:
13
+ # ── Build & push versioned Docker images ────────────────────────────────────
14
+ docker-publish:
15
+ name: Publish ${{ matrix.service }} image
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ matrix:
19
+ include:
20
+ - service: gateway
21
+ dockerfile: Dockerfile
22
+ image: ghcr.io/${{ github.repository }}/acr-gateway
23
+ - service: killswitch
24
+ dockerfile: Dockerfile.killswitch
25
+ image: ghcr.io/${{ github.repository }}/acr-killswitch
26
+
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+
30
+ - name: Log in to GitHub Container Registry
31
+ uses: docker/login-action@v3
32
+ with:
33
+ registry: ghcr.io
34
+ username: ${{ github.actor }}
35
+ password: ${{ secrets.GITHUB_TOKEN }}
36
+
37
+ - name: Extract metadata
38
+ id: meta
39
+ uses: docker/metadata-action@v5
40
+ with:
41
+ images: ${{ matrix.image }}
42
+ tags: |
43
+ type=semver,pattern={{version}}
44
+ type=semver,pattern={{major}}.{{minor}}
45
+ type=semver,pattern={{major}}
46
+ type=sha,prefix=sha-
47
+
48
+ - name: Set up Docker Buildx
49
+ uses: docker/setup-buildx-action@v3
50
+
51
+ - name: Build and push ${{ matrix.service }}
52
+ uses: docker/build-push-action@v6
53
+ with:
54
+ context: .
55
+ file: ${{ matrix.dockerfile }}
56
+ push: true
57
+ tags: ${{ steps.meta.outputs.tags }}
58
+ labels: ${{ steps.meta.outputs.labels }}
59
+ cache-from: type=gha
60
+ cache-to: type=gha,mode=max
61
+
62
+ # ── Create GitHub Release ────────────────────────────────────────────────────
63
+ github-release:
64
+ name: Create GitHub Release
65
+ runs-on: ubuntu-latest
66
+ needs: docker-publish
67
+ permissions:
68
+ contents: write
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+
72
+ - name: Create release
73
+ uses: softprops/action-gh-release@v2
74
+ with:
75
+ generate_release_notes: true
76
+ make_latest: true
@@ -0,0 +1,126 @@
1
+ name: Security
2
+
3
+ on:
4
+ push:
5
+ branches: ["main", "develop"]
6
+ pull_request:
7
+ branches: ["main"]
8
+ schedule:
9
+ - cron: "0 9 * * 1"
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ secret-hygiene:
16
+ name: Secret hygiene
17
+ runs-on: ubuntu-latest
18
+ permissions:
19
+ contents: read
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - uses: actions/setup-python@v5
24
+ with:
25
+ python-version: "3.11"
26
+
27
+ - name: Block dev-secret patterns in production-facing assets
28
+ run: python scripts/check_no_dev_secrets.py
29
+
30
+ codeql:
31
+ name: CodeQL
32
+ runs-on: ubuntu-latest
33
+ permissions:
34
+ actions: read
35
+ contents: read
36
+ security-events: write
37
+ strategy:
38
+ fail-fast: false
39
+ matrix:
40
+ language: ["python"]
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+
44
+ - uses: actions/setup-python@v5
45
+ with:
46
+ python-version: "3.11"
47
+ cache: pip
48
+
49
+ - name: Initialize CodeQL
50
+ uses: github/codeql-action/init@v3
51
+ with:
52
+ languages: ${{ matrix.language }}
53
+
54
+ - name: Install dependencies
55
+ run: pip install -e ".[dev]"
56
+
57
+ - name: Analyze
58
+ uses: github/codeql-action/analyze@v3
59
+
60
+ semgrep:
61
+ name: Semgrep
62
+ runs-on: ubuntu-latest
63
+ permissions:
64
+ contents: read
65
+ security-events: write
66
+ steps:
67
+ - uses: actions/checkout@v4
68
+
69
+ - name: Run Semgrep
70
+ uses: returntocorp/semgrep-action@v1
71
+ with:
72
+ config: >-
73
+ p/python
74
+ p/dockerfile
75
+ p/secrets
76
+
77
+ gitleaks:
78
+ name: Gitleaks
79
+ runs-on: ubuntu-latest
80
+ permissions:
81
+ contents: read
82
+ security-events: write
83
+ steps:
84
+ - uses: actions/checkout@v4
85
+
86
+ - name: Run Gitleaks
87
+ uses: gitleaks/gitleaks-action@v2
88
+ env:
89
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
90
+
91
+ trivy-and-sbom:
92
+ name: Trivy and SBOM
93
+ runs-on: ubuntu-latest
94
+ permissions:
95
+ contents: read
96
+ security-events: write
97
+ steps:
98
+ - uses: actions/checkout@v4
99
+
100
+ - name: Trivy filesystem scan
101
+ uses: aquasecurity/trivy-action@0.24.0
102
+ with:
103
+ scan-type: fs
104
+ scan-ref: .
105
+ format: sarif
106
+ output: trivy-results.sarif
107
+ severity: HIGH,CRITICAL
108
+
109
+ - name: Upload Trivy SARIF
110
+ uses: github/codeql-action/upload-sarif@v3
111
+ with:
112
+ sarif_file: trivy-results.sarif
113
+
114
+ - name: Generate CycloneDX SBOM
115
+ uses: anchore/sbom-action@v0
116
+ with:
117
+ path: .
118
+ format: cyclonedx-json
119
+ output-file: sbom.cdx.json
120
+
121
+ - name: Upload SBOM artifact
122
+ uses: actions/upload-artifact@v4
123
+ with:
124
+ name: cyclonedx-sbom
125
+ path: sbom.cdx.json
126
+ retention-days: 30
@@ -0,0 +1,28 @@
1
+ # OS and editor
2
+ .DS_Store
3
+ Thumbs.db
4
+ *.swp
5
+ *.swo
6
+ *~
7
+ .idea/
8
+ .vscode/
9
+ *.sublime-*
10
+
11
+ # Local / env
12
+ .env
13
+ .env.local
14
+ *.local
15
+
16
+ # Build / generated (if any doc tooling is added later)
17
+ _site/
18
+ .cache/
19
+ *.pyc
20
+ __pycache__/
21
+
22
+ # Generated local policy bundle artifacts
23
+ implementations/acr-control-plane/var/policy_bundles/
24
+
25
+ # Optional: uncomment if using a doc generator
26
+ # node_modules/
27
+ # .venv/
28
+ # venv/
@@ -0,0 +1,40 @@
1
+ # Stage 1: build
2
+ FROM python:3.12-slim AS builder
3
+ # Version for hatch-vcs (no .git in build context). Set via --build-arg
4
+ # from CI; defaults to 0.0.0+unknown for local builds.
5
+ ARG SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0+unknown
6
+ WORKDIR /build
7
+ RUN apt-get update && apt-get install -y --no-install-recommends gcc libpq-dev \
8
+ && rm -rf /var/lib/apt/lists/*
9
+ COPY pyproject.toml README.md ./
10
+ COPY src/ ./src/
11
+ RUN pip install --no-cache-dir build wheel \
12
+ && pip wheel --no-cache-dir --wheel-dir /wheels .
13
+
14
+ # Stage 2: runtime
15
+ FROM python:3.12-slim AS runtime
16
+ WORKDIR /app
17
+ RUN apt-get update && apt-get install -y --no-install-recommends libpq5 curl \
18
+ && rm -rf /var/lib/apt/lists/*
19
+ COPY --from=builder /wheels /wheels
20
+ RUN pip install --no-cache-dir --no-index --find-links=/wheels acr-control-plane \
21
+ && rm -rf /wheels
22
+ COPY src/ ./src/
23
+ COPY policies/ ./policies/
24
+ COPY alembic.ini ./
25
+ # Migration entrypoint shared by the K8s init container, the docker-compose
26
+ # `acr-migrate` one-shot service, and CI. Installed on PATH so it can be
27
+ # invoked simply as `run-migrations` from any container using this image.
28
+ COPY scripts/run-migrations.sh /usr/local/bin/run-migrations
29
+ RUN chmod +x /usr/local/bin/run-migrations
30
+
31
+ ENV PYTHONPATH=/app/src
32
+ ENV PYTHONUNBUFFERED=1
33
+ ENV WEB_CONCURRENCY=2
34
+
35
+ EXPOSE 8000
36
+
37
+ RUN useradd -r -u 1000 acr
38
+ USER acr
39
+
40
+ CMD ["uvicorn", "acr.main:app", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,33 @@
1
+ # Stage 1: build
2
+ FROM python:3.12-slim AS builder
3
+ # Version for hatch-vcs (no .git in build context). Set via --build-arg
4
+ # from CI; defaults to 0.0.0+unknown for local builds.
5
+ ARG SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0+unknown
6
+ WORKDIR /build
7
+ RUN apt-get update && apt-get install -y --no-install-recommends gcc \
8
+ && rm -rf /var/lib/apt/lists/*
9
+ COPY pyproject.toml README.md ./
10
+ COPY src/ ./src/
11
+ RUN pip install --no-cache-dir build wheel \
12
+ && pip wheel --no-cache-dir --wheel-dir /wheels .
13
+
14
+ # Stage 2: runtime
15
+ FROM python:3.12-slim AS runtime
16
+ WORKDIR /app
17
+ RUN apt-get update && apt-get install -y --no-install-recommends curl \
18
+ && rm -rf /var/lib/apt/lists/*
19
+ COPY --from=builder /wheels /wheels
20
+ RUN pip install --no-cache-dir --no-index --find-links=/wheels acr-control-plane \
21
+ && rm -rf /wheels
22
+ COPY src/ ./src/
23
+
24
+ ENV PYTHONPATH=/app/src
25
+ ENV PYTHONUNBUFFERED=1
26
+ ENV WEB_CONCURRENCY=2
27
+
28
+ EXPOSE 8443
29
+
30
+ RUN useradd -r -u 1000 acr
31
+ USER acr
32
+
33
+ CMD ["uvicorn", "acr.pillar5_containment.service:app", "--host", "0.0.0.0", "--port", "8443"]