Skip to content

Make deployment policy capability-aware and isolate privileged roles #11

Description

@Nickfost

Evidence on current main

Audited e483998b34595e51426c3b14589a74ca09ae78a9.

No open or closed issue/PR in this repository accurately tracks this combined contract gap; the only related closed work is the general update guide in #10.

User/operator impact

A GitHub Free organization using private repositories can read the current hard rule as a protection guarantee that the plan cannot provide. A template adopter can also declare deployment host groups without a machine-checkable separation between ordinary CI, persistent test environments, image builders, production deployers, and narrowly privileged ref writers. That is misleading at a security boundary even though the example configuration contains no secrets.

Bounded scope

Make the public deployment portion of the template truthful and enforceable:

  1. represent repository visibility and relevant GitHub-plan capabilities without assuming an upgrade;
  2. distinguish logical environment names from the mechanism that actually gates an immutable deployment;
  3. support either a genuinely available protected-Environment path or an explicit host-local/external/manual exact-head approval path;
  4. define generic, project-neutral role identities for image building, persistent testing, development deployment, production deployment, and an optional isolated ref writer;
  5. validate that those roles do not reuse ordinary-CI runner groups, routing labels, credentials, or authority; and
  6. keep production credentials and production network authority unavailable to ordinary CI.

If core #22/#23 have not stabilized enough to define executable role fields, the minimum safe first change is to mark the current deployment objects as logical inventory only, remove unconditional Environment claims, and reserve/version the future role-policy boundary rather than inventing an unproved API.

Non-goals

  • Do not implement the core deployer, tester, or GitHub bootstrap installers.
  • Do not create or modify GitHub Environments, runner groups, secrets, variables, plans, repository visibility, or infrastructure.
  • Do not add Windows/PowerShell paths.
  • Do not copy any project-specific consumer policy into the public template.
  • Do not grant repository-write or deployment authority to ordinary CI.

Cross-repository compatibility

  • Depends on the role boundaries in core #22 and #23; it must not contradict the generic worker-host contract in core #21.
  • The ref-writer form must remain a separate least-privilege role: exact reviewed head, immutable inputs, no checkout or project execution when unnecessary, no production/management route, non-force compare-and-swap, and an explicit rollback path.
  • Existing schema-v3 adopters need a documented migration or an intentional compatible optional extension.
  • The public/private project bridge must continue to keep privileged work in a private delivery repository while public pull-request CI remains unprivileged.

Acceptance criteria

  • Documentation uses capability-aware language and states that GitHub Free private repositories do not have protected Environments or Environment secrets.
  • A production declaration cannot validate based only on an unavailable GitHub Environment approval.
  • The supported fallback records a manual/external exact-head approval before a privileged identity receives immutable artifact inputs; approval evidence contains no secret values.
  • Schema/semantic validation (or an explicit versioned companion policy) distinguishes ordinary CI, persistent tester, image builder, development deployer, production deployer, and optional deploy-ref-writer roles.
  • Validators reject runner-group/routing-label reuse across incompatible role kinds and reject production credentials/authority in ordinary CI.
  • Initializer and fictional examples cover both an Environment-capable path and a GitHub-Free/private fallback, or deliberately omit deployment roles until the operator opts in.
  • Tests fail for capability overclaims, self-approved production, moving refs/tags, mutable artifact promotion, and conflated role authority.
  • Documentation identifies host-local and external secret-store paths without implying that a secret store itself supplies approval.
  • Linux/Bash-only operator guidance remains copyable and secret-free.

Validation

At minimum:

./scripts/validate.sh --strict
python3 scripts/test_policy.py
python3 scripts/scan_committed_secrets.py --commit <full-reviewed-commit>

Add the smallest deterministic fixtures that prove the two capability paths and role-isolation failures.

Dependencies

  • Design input: core #22 and #23.
  • GitHub-side bootstrap remains core #27, not this issue.
  • Documentation ordering/cross-links belong in core #24.
  • This can proceed in parallel with worker-host installer completion in core #21, provided it does not invent deployer/tester runtime interfaces.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions