AEGISCONTROL

Security policy

Status

This repository is a local protocol demonstrator. It has not been independently audited and must not be connected to production systems or given real credentials.

The optional hardened lab improves the local trust boundaries with mTLS, SPIFFE-format certificate identities, explicit RBAC, external OPA, PostgreSQL authority, Temporal, OpenBao Transit, typed SIEM adapters, signed one-shot executor grants, a dedicated executor database role, an out-of-process mTLS executor, a signed ExecutionProof, signed request-bound AuthZEN decisions, a fail-closed admission verifier, a separately keyed mTLS/read-only observer, signed transparency receipts, S3 Object Lock COMPLIANCE and a durable emergency stop. Its certificates are still issued by a local development CA for the Windows application profile. The SOTA profile exercises TLS 1.3 between two genuine SPIRE X.509-SVIDs and qualifies the Kubernetes NetworkPolicy adapter, proof webhook, observer, outage/recovery, RBAC, admission and Cilium on one disposable local cluster. It has not been independently reviewed or qualified across a cluster/CNI matrix. OpenBao is not an HSM or separate administrative domain. The WORM lab shares the host and the JSON transparency format is not a SCITT conformance claim. These controls do not change the production prohibition.

All generated private keys, databases, downloaded lab binaries, and logs are under ignored .aegis-lab/. Treat that directory as sensitive. Never place real credentials or customer data in it. Use npm run lab:stop plus npm run lab:postgres:stop after application tests, and npm run sota:pause after Kubernetes tests.

Never set AEGIS_KUBERNETES_MODE=real against a cluster that is not disposable and explicitly authorized. Real mode creates and deletes NetworkPolicies and patches the reserved aegis.io/quarantine-id pod label.

Supported versions

Only the latest commit in this repository is maintained. There are no published production releases yet.

Reporting a vulnerability

Do not open a public issue containing exploit details, credentials, customer data, or a working bypass. Contact the repository owner privately and include:

Until a private reporting address and response SLA are published, this project must not claim a coordinated vulnerability-disclosure program.

Dependency policy

The dependency set is small on purpose and every addition is a decision, not a convenience. Current production dependencies: pg, @kubernetes/client-node, @temporalio/*, @aws-sdk/client-s3, @opentelemetry/api. The Rust verifier under verifier/ adds seven, chosen so an auditor can read the whole set.

Two of the verifier's seven — ciborium and coset — were added for a reason worth stating, because they look like the policy above being bent. AEGIS encodes CBOR and COSE by hand (src/cbor.ts, src/cose.ts) in a deliberately small, encode-only subset: no floats, no indefinite lengths, no decoder. A hand-written encoder is only defensible if something that is not AEGIS reads what it produces, so those two crates exist precisely to be the independent reader. Putting them on the verifier side rather than the production side is the whole point: the parser that faces untrusted bytes is a third party's, and the code that faces the network never decodes CBOR at all.

Security-critical change policy

Changes to canonicalization, signatures, identities, policy decisions, capability consumption, evidence provenance, executor state transitions, audit, or restoration require:

  1. a new adversarial regression test;
  2. explicit review of fail-open/fail-closed behaviour;
  3. migration and replay analysis for stored artifacts;
  4. an update to the threat model when a trust boundary changes.

Production development additionally requires protected branches, two-person review for policy/signing paths, signed releases, SBOM/provenance, dependency and secret scanning, and an independent assessment before any write credential. The assessor handoff is defined in docs/security-audit-package.md; only an external signed report can close that gate.

Where that list stands, 2026-09-01

Written down rather than left implied: "production development requires X" reads as "X is planned", and an assessor needs to know which half is already true.

Requirement State
Signed commits In place from 39d8152 onward, and verifiable by a reviewer rather than only on GitHub. Commits made locally carry the author's SSH key, whose public half is committed as .github/allowed_signers; merges performed through the GitHub interface carry GitHub's own web-flow key instead and are marked verified on GitHub's side. To check the first kind from a fresh clone: git config gpg.ssh.allowedSignersFile .github/allowed_signers && git log --show-signature. Without that config git reports No principal matched — it sees a signature but has nothing to match it against. Commits before 39d8152 are unsigned and predate signing being configured.
Signed releases and SBOM In place. .github/workflows/release.yml publishes only after the gates that guard main pass on the tagged commit, and attaches a CycloneDX SBOM, the shared canonical-vector corpus, the independent verifier binary and SHA256SUMS. The tag itself is signed.
Build provenance Described, not attested. GitHub refuses to persist attestations for a user-owned private repository — Feature not available for user-owned private repositories — so the release ships a provenance.json statement generated by the workflow and signed by nobody. The signed tag binds the release to a commit and SHA256SUMS binds that commit's build to the bytes; what is missing is a signature over the builder's identity. The attestation step is gated on the repository being public and starts working by itself if that changes.
Dependency and secret scanning In place. supply-chain runs gitleaks over the working tree and the commit history, and Trivy over dependencies and manifests.
CODEOWNERS on policy and signing paths Present, and advisory only — see the row below.
Protected branches Not in place, and not currently obtainable. GitHub refuses both the branch-protection and the rulesets API on a private repository under a Free plan: Upgrade to GitHub Pro or make this repository public. Without it CODEOWNERS cannot be enforced and a direct push to main is possible.
Two-person review for policy and signing paths Not in place. It presupposes protected branches, and a second person.
Independent assessment Not in place. Unchanged: only an external signed report closes that gate.

The two open items are one item twice — a single-author repository cannot enforce review on itself. Signed commits and a full CI run on every push make a bad push detectable, not impossible, and that distinction is the whole difference between a control and a habit.