This document describes the security controls that protect the Aranya release pipeline. These controls also enforce our QA process: peer review ensures test coverage, CI runs automated tests on every PR and release, and required status checks and approvals must pass before merging. For the release process itself, see Release Process.
All items below are tracked under aranya#730.
| Section | Action | Level | Repos affected |
|---|---|---|---|
| Branch Protections | Add release/**/* wildcard branch protection rule |
org | all |
| Branch Protections | Enable “Require review from Code Owners” at org level | org | all |
| CI/CD | Update release.yml trigger to include branches: release/**/*
|
repo (workflow) | aranya |
| CI/CD | Update publish.yml trigger to include branches: release/**/*
|
repo (workflow) | aranya |
| CI/CD | Update release-plz.yml trigger to include branches: release/**/*
|
repo (workflow) | aranya-core |
| Release Environment Protections | Configure release environment with required reviewers and deployment branch restrictions |
env-level: release
|
aranya, aranya-core |
| Release Environment Protections | Reference environment: release in release workflow jobs |
repo (workflow) | aranya, aranya-core |
| Secrets Management | Store ARANYA_BOT_CRATESIO_CARGO_LOGIN_KEY in release environment |
env-level: release
|
aranya, aranya-core |
Default branch protection rules are configured at the org level (aranya-project org rulesets) and apply to all repos. Repo-level overrides or additional rules can be configured per repo under Settings > Rules > Rulesets.
The following branches must be protected:
main – used for normal product releases (major and minor versions). Protected by org-level default rules.release/**/* – used for patch releases and any other releases not performed from main. Protected by an org-level wildcard branch protection rule.Required branch protection settings. These are configured at the org level unless noted as repo-specific:
| Setting | Value | Level | Status | Notes |
|---|---|---|---|---|
| Require a pull request before merging | Enabled | org | Configured (org ruleset) | No direct pushes to protected branches |
| Required approvals | 2 | org | Configured (org ruleset) | Release PRs require at least 2 internal approvals |
| Dismiss stale pull request approvals when new commits are pushed | Enabled | org | Configured (org ruleset) | Prevents approval of outdated code |
| Require review from Code Owners | Enabled | org | Configured (org ruleset) | At least one CODEOWNERS reviewer must approve |
| Require status checks to pass before merging | Enabled | repo | Configured (per-repo rulesets) | Repo-specific: each repo has different checks; see CI/CD |
| Require branches to be up to date before merging | Enabled | org | Configured (org ruleset) | Ensures PRs are rebased before merging |
| Bypass permissions |
TeamLeads team and repo admins |
org | Configured (org ruleset) | Intentional: team leads may bypass with a documented paper trail |
| Restrict force pushes | Enabled | org | Configured (org ruleset non_fast_forward rule) |
Force pushes are prevented on all protected branches |
| Restrict deletions | Enabled | org | Configured (org ruleset) | Prevent deletion of protected branches |
Branch protections should only be bypassed by team members with elevated permissions under special documented circumstances (e.g. by team leads or admin with a documented paper trail explaining the rationale).
.github/CODEOWNERS file in each repo)
CI/CD runs on main and all PRs/feature branches. Workflow files are repo-level (committed in each repo’s .github/workflows/ directory). Required status checks are also repo-level since each repo has different workflows and jobs.
| Repo | Workflows | Required status checks (rulesets) |
|---|---|---|
| aranya | .github/workflows/ |
Rulesets settings |
| aranya-core | .github/workflows/ |
Rulesets settings |
The release-critical workflows are release.yml and publish.yml (aranya) and release-plz.yml (aranya-core). These handle tagging, publishing crates to crates.io, and uploading release artifacts.
Additional CI/CD policies:
main and release/**/* branches: release.yml and publish.yml (aranya) and release-plz.yml (aranya-core).Release workflows (release.yml and publish.yml in aranya, release-plz.yml in aranya-core) use a GitHub Environment to gate access to release secrets and provide an additional approval step. Environment settings (repo-level): aranya, aranya-core.
| Setting | Value | Level | Workflow files | Notes |
|---|---|---|---|---|
| Deployment branches |
main and release/**/*
|
env-level: release
|
– | Restricts which branches can deploy to this environment |
| Required reviewers | At least 1 team lead or release lead | env-level: release
|
– | Human approval gate during the release workflow, after the release PR has been merged. This is separate from PR review requirements. |
Workflow environment: release
|
Referenced in release jobs | repo (workflow) |
release.yml (aranya), release-plz.yml (aranya-core) |
Required for environment protections to take effect |
Required reviewers is a built-in GitHub feature for environment protections. When a workflow job references an environment with required reviewers, GitHub pauses the workflow and notifies the designated reviewers. The workflow cannot proceed until a reviewer approves the deployment in the GitHub Actions UI. No third-party actions are needed.
Limitation: Environment approvals only require a single approval from anyone on the reviewer list — there is no way to require multiple approvals or to require a specific person plus additional approvers. For multi-reviewer requirements on the release PR (e.g., 1 lead + 2 other reviewers), use branch protection rules on release/**/* branches instead. The environment gate serves as a final confirmation from a team lead after the PR has already been reviewed and merged.
The release environment is configured in both aranya and aranya-core. The release workflow jobs in both repos reference it:
# aranya release.yml (https://github.com/aranya-project/aranya/blob/main/.github/workflows/release.yml)
jobs:
tag:
environment: release
...
# aranya-core release-plz.yml (https://github.com/aranya-project/aranya-core/blob/main/.github/workflows/release-plz.yml)
jobs:
release-plz-release:
environment: release
...
This prevents an attacker from modifying a workflow on an unprotected branch to trigger an unauthorized release, since the environment will block execution and deny access to secrets.
Release credentials are scoped to the release environment rather than stored as repo-level secrets, so unprotected branches cannot access them. GitHub does not support org-level environments (community request), so environment-scoped secrets must be duplicated in each repo’s release environment that needs them.
| Secret name | Scope | Workflow files | Location |
|---|---|---|---|
ARANYA_BOT_CRATESIO_CARGO_LOGIN_KEY |
env-level: release
|
release.yml (aranya), release-plz.yml (aranya-core) |
Settings > Environments > release > Environment secrets in each repo |
ARANYA_BOT_CRATESIO_CARGO_LOGIN_KEY is stored in the release environment in both repos (aranya, aranya-core). The workflows reference this secret as secrets.ARANYA_BOT_CRATESIO_CARGO_LOGIN_KEY. Because org-level environments are not available, the secret is configured separately in each repo’s release environment.