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.
- acr_control_plane-1.1.3/.env.example +123 -0
- acr_control_plane-1.1.3/.env.production.example +64 -0
- acr_control_plane-1.1.3/.github/workflows/ci.yml +180 -0
- acr_control_plane-1.1.3/.github/workflows/release.yml +76 -0
- acr_control_plane-1.1.3/.github/workflows/security.yml +126 -0
- acr_control_plane-1.1.3/.gitignore +28 -0
- acr_control_plane-1.1.3/Dockerfile +40 -0
- acr_control_plane-1.1.3/Dockerfile.killswitch +33 -0
- acr_control_plane-1.1.3/LICENSE +111 -0
- acr_control_plane-1.1.3/PKG-INFO +378 -0
- acr_control_plane-1.1.3/README.md +334 -0
- acr_control_plane-1.1.3/alembic.ini +39 -0
- acr_control_plane-1.1.3/deploy/k8s/base/gateway-configmap.yaml +37 -0
- acr_control_plane-1.1.3/deploy/k8s/base/gateway-deployment.yaml +107 -0
- acr_control_plane-1.1.3/deploy/k8s/base/gateway-secret.example.yaml +21 -0
- acr_control_plane-1.1.3/deploy/k8s/base/gateway-service.yaml +10 -0
- acr_control_plane-1.1.3/deploy/k8s/base/hpas.yaml +77 -0
- acr_control_plane-1.1.3/deploy/k8s/base/ingress.yaml +39 -0
- acr_control_plane-1.1.3/deploy/k8s/base/killswitch-deployment.yaml +89 -0
- acr_control_plane-1.1.3/deploy/k8s/base/killswitch-service.yaml +10 -0
- acr_control_plane-1.1.3/deploy/k8s/base/kustomization.yaml +17 -0
- acr_control_plane-1.1.3/deploy/k8s/base/namespace.yaml +4 -0
- acr_control_plane-1.1.3/deploy/k8s/base/networkpolicy.yaml +149 -0
- acr_control_plane-1.1.3/deploy/k8s/base/opa-deployment.yaml +70 -0
- acr_control_plane-1.1.3/deploy/k8s/base/opa-service.yaml +10 -0
- acr_control_plane-1.1.3/deploy/k8s/base/pdbs.yaml +32 -0
- acr_control_plane-1.1.3/deploy/k8s/base/rbac.yaml +33 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/README.md +84 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/external-secret.yaml +83 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/gateway-configmap-patch.yaml +34 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/gateway-deployment-patch.yaml +24 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/ingress-patch.yaml +27 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/killswitch-deployment-patch.yaml +24 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/kustomization.yaml +25 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/namespace-patch.yaml +9 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/networkpolicy-production.yaml +127 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/opa-deployment-patch.yaml +24 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/remove-base-gateway-netpol.yaml +6 -0
- acr_control_plane-1.1.3/deploy/k8s/overlays/production/remove-base-killswitch-netpol.yaml +6 -0
- acr_control_plane-1.1.3/docker-compose.yml +190 -0
- acr_control_plane-1.1.3/docs/api.md +511 -0
- acr_control_plane-1.1.3/docs/compliance/README.md +56 -0
- acr_control_plane-1.1.3/docs/compliance/control-mapping.md +58 -0
- acr_control_plane-1.1.3/docs/compliance/evidence-package.md +56 -0
- acr_control_plane-1.1.3/docs/compliance/external-assessment-scope.md +56 -0
- acr_control_plane-1.1.3/docs/compliance/shared-responsibility-matrix.md +27 -0
- acr_control_plane-1.1.3/docs/compliance/threat-model.md +150 -0
- acr_control_plane-1.1.3/docs/configuration.md +100 -0
- acr_control_plane-1.1.3/docs/deployment.md +170 -0
- acr_control_plane-1.1.3/docs/enterprise-roadmap.md +186 -0
- acr_control_plane-1.1.3/docs/failure-load-dr-validation-2026-04-08.md +230 -0
- acr_control_plane-1.1.3/docs/orchestrators.md +145 -0
- acr_control_plane-1.1.3/docs/production_install.md +171 -0
- acr_control_plane-1.1.3/docs/provenance-and-verification.md +98 -0
- acr_control_plane-1.1.3/docs/sdk.md +113 -0
- acr_control_plane-1.1.3/examples/n8n/README.md +95 -0
- acr_control_plane-1.1.3/examples/n8n/acr_sensitive_action_workflow.json +254 -0
- acr_control_plane-1.1.3/examples/protected_executor/.env.example +3 -0
- acr_control_plane-1.1.3/examples/protected_executor/Dockerfile +17 -0
- acr_control_plane-1.1.3/examples/protected_executor/README.md +96 -0
- acr_control_plane-1.1.3/examples/protected_executor/app.py +84 -0
- acr_control_plane-1.1.3/examples/sample_agent/README.md +55 -0
- acr_control_plane-1.1.3/examples/sample_agent/agent.py +146 -0
- acr_control_plane-1.1.3/examples/sample_agent/tools.py +38 -0
- acr_control_plane-1.1.3/policies/acr/common.rego +86 -0
- acr_control_plane-1.1.3/policies/acr/customer_support.rego +53 -0
- acr_control_plane-1.1.3/pyproject.toml +126 -0
- acr_control_plane-1.1.3/scripts/build_compliance_package.py +171 -0
- acr_control_plane-1.1.3/scripts/check_no_dev_secrets.py +53 -0
- acr_control_plane-1.1.3/scripts/generate_secrets.py +72 -0
- acr_control_plane-1.1.3/scripts/run-migrations.sh +36 -0
- acr_control_plane-1.1.3/sdks/typescript/README.md +69 -0
- acr_control_plane-1.1.3/sdks/typescript/dist/index.d.ts +129 -0
- acr_control_plane-1.1.3/sdks/typescript/dist/index.js +197 -0
- acr_control_plane-1.1.3/sdks/typescript/package.json +26 -0
- acr_control_plane-1.1.3/sdks/typescript/src/index.ts +323 -0
- acr_control_plane-1.1.3/sdks/typescript/tsconfig.json +14 -0
- acr_control_plane-1.1.3/src/acr/__init__.py +8 -0
- acr_control_plane-1.1.3/src/acr/auth/router.py +96 -0
- acr_control_plane-1.1.3/src/acr/common/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/common/correlation.py +24 -0
- acr_control_plane-1.1.3/src/acr/common/errors.py +165 -0
- acr_control_plane-1.1.3/src/acr/common/oidc.py +160 -0
- acr_control_plane-1.1.3/src/acr/common/operator_auth.py +97 -0
- acr_control_plane-1.1.3/src/acr/common/redis_client.py +45 -0
- acr_control_plane-1.1.3/src/acr/common/time.py +13 -0
- acr_control_plane-1.1.3/src/acr/config.py +283 -0
- acr_control_plane-1.1.3/src/acr/db/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/db/database.py +59 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/env.py +68 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/script.py.mako +28 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0001_initial.py +146 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0002_cascade_fks_and_indexes.py +113 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0003_status_check_constraints.py +66 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0004_approval_execution_result.py +27 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0005_operator_credentials.py +42 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0006_policy_drafts.py +40 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0007_policy_releases.py +49 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0008_policy_release_artifacts.py +27 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0009_policy_release_activation.py +35 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0010_drift_baseline_versions.py +71 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0011_monthly_partitioning.py +147 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0012_agent_registry_expansion.py +104 -0
- acr_control_plane-1.1.3/src/acr/db/migrations/versions/0013_policy_decision_modify.py +33 -0
- acr_control_plane-1.1.3/src/acr/db/models.py +338 -0
- acr_control_plane-1.1.3/src/acr/gateway/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/gateway/auth.py +33 -0
- acr_control_plane-1.1.3/src/acr/gateway/executor.py +125 -0
- acr_control_plane-1.1.3/src/acr/gateway/executor_auth.py +265 -0
- acr_control_plane-1.1.3/src/acr/gateway/executor_integrations.py +184 -0
- acr_control_plane-1.1.3/src/acr/gateway/middleware.py +46 -0
- acr_control_plane-1.1.3/src/acr/gateway/models.py +63 -0
- acr_control_plane-1.1.3/src/acr/gateway/proxy.py +36 -0
- acr_control_plane-1.1.3/src/acr/gateway/router.py +736 -0
- acr_control_plane-1.1.3/src/acr/gateway/spend_control.py +96 -0
- acr_control_plane-1.1.3/src/acr/main.py +715 -0
- acr_control_plane-1.1.3/src/acr/operator_console/__init__.py +1 -0
- acr_control_plane-1.1.3/src/acr/operator_console/router.py +35 -0
- acr_control_plane-1.1.3/src/acr/operator_console/static/app.js +909 -0
- acr_control_plane-1.1.3/src/acr/operator_console/static/index.html +510 -0
- acr_control_plane-1.1.3/src/acr/operator_console/static/styles.css +348 -0
- acr_control_plane-1.1.3/src/acr/operator_keys/__init__.py +1 -0
- acr_control_plane-1.1.3/src/acr/operator_keys/models.py +34 -0
- acr_control_plane-1.1.3/src/acr/operator_keys/router.py +62 -0
- acr_control_plane-1.1.3/src/acr/operator_keys/service.py +111 -0
- acr_control_plane-1.1.3/src/acr/pillar1_identity/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/pillar1_identity/models.py +171 -0
- acr_control_plane-1.1.3/src/acr/pillar1_identity/registry.py +322 -0
- acr_control_plane-1.1.3/src/acr/pillar1_identity/router.py +233 -0
- acr_control_plane-1.1.3/src/acr/pillar1_identity/validator.py +94 -0
- acr_control_plane-1.1.3/src/acr/pillar2_policy/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/pillar2_policy/engine.py +246 -0
- acr_control_plane-1.1.3/src/acr/pillar2_policy/models.py +38 -0
- acr_control_plane-1.1.3/src/acr/pillar2_policy/output_filter.py +106 -0
- acr_control_plane-1.1.3/src/acr/pillar3_drift/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/pillar3_drift/baseline.py +155 -0
- acr_control_plane-1.1.3/src/acr/pillar3_drift/detector.py +158 -0
- acr_control_plane-1.1.3/src/acr/pillar3_drift/governance.py +177 -0
- acr_control_plane-1.1.3/src/acr/pillar3_drift/models.py +70 -0
- acr_control_plane-1.1.3/src/acr/pillar3_drift/signals.py +90 -0
- acr_control_plane-1.1.3/src/acr/pillar4_observability/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/pillar4_observability/evidence.py +94 -0
- acr_control_plane-1.1.3/src/acr/pillar4_observability/integrity.py +88 -0
- acr_control_plane-1.1.3/src/acr/pillar4_observability/otel.py +117 -0
- acr_control_plane-1.1.3/src/acr/pillar4_observability/schema.py +118 -0
- acr_control_plane-1.1.3/src/acr/pillar4_observability/telemetry.py +148 -0
- acr_control_plane-1.1.3/src/acr/pillar5_containment/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/pillar5_containment/graduated.py +149 -0
- acr_control_plane-1.1.3/src/acr/pillar5_containment/killswitch.py +119 -0
- acr_control_plane-1.1.3/src/acr/pillar5_containment/models.py +54 -0
- acr_control_plane-1.1.3/src/acr/pillar5_containment/router.py +53 -0
- acr_control_plane-1.1.3/src/acr/pillar5_containment/service.py +208 -0
- acr_control_plane-1.1.3/src/acr/pillar6_authority/__init__.py +0 -0
- acr_control_plane-1.1.3/src/acr/pillar6_authority/approval.py +247 -0
- acr_control_plane-1.1.3/src/acr/pillar6_authority/models.py +52 -0
- acr_control_plane-1.1.3/src/acr/pillar6_authority/router.py +101 -0
- acr_control_plane-1.1.3/src/acr/pillar6_authority/tiering.py +55 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/__init__.py +1 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/bundles.py +54 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/distribution.py +102 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/models.py +84 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/publisher.py +192 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/releases.py +198 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/router.py +223 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/service.py +70 -0
- acr_control_plane-1.1.3/src/acr/policy_studio/simulator.py +109 -0
- acr_control_plane-1.1.3/src/acr/sdk/__init__.py +35 -0
- acr_control_plane-1.1.3/src/acr/sdk/client.py +405 -0
- acr_control_plane-1.1.3/src/acr/sdk/errors.py +34 -0
- acr_control_plane-1.1.3/src/acr/sdk/langgraph.py +173 -0
- acr_control_plane-1.1.3/tests/conftest.py +129 -0
- acr_control_plane-1.1.3/tests/integration/__init__.py +0 -0
- acr_control_plane-1.1.3/tests/integration/conftest.py +114 -0
- acr_control_plane-1.1.3/tests/integration/test_integration.py +165 -0
- acr_control_plane-1.1.3/tests/test_authority.py +182 -0
- acr_control_plane-1.1.3/tests/test_authority_advanced.py +294 -0
- acr_control_plane-1.1.3/tests/test_concurrency.py +205 -0
- acr_control_plane-1.1.3/tests/test_containment.py +40 -0
- acr_control_plane-1.1.3/tests/test_drift.py +80 -0
- acr_control_plane-1.1.3/tests/test_drift_db.py +413 -0
- acr_control_plane-1.1.3/tests/test_drift_governance_api.py +90 -0
- acr_control_plane-1.1.3/tests/test_enterprise_hardening.py +228 -0
- acr_control_plane-1.1.3/tests/test_evidence.py +75 -0
- acr_control_plane-1.1.3/tests/test_executor.py +232 -0
- acr_control_plane-1.1.3/tests/test_gateway.py +321 -0
- acr_control_plane-1.1.3/tests/test_identity.py +380 -0
- acr_control_plane-1.1.3/tests/test_killswitch_service.py +198 -0
- acr_control_plane-1.1.3/tests/test_observability.py +122 -0
- acr_control_plane-1.1.3/tests/test_operator_keys.py +155 -0
- acr_control_plane-1.1.3/tests/test_policy.py +37 -0
- acr_control_plane-1.1.3/tests/test_policy_engine.py +235 -0
- acr_control_plane-1.1.3/tests/test_policy_studio.py +309 -0
- acr_control_plane-1.1.3/tests/test_sdk.py +185 -0
- acr_control_plane-1.1.3/tests/test_secret_hygiene.py +32 -0
- 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"]
|