From f9368205b6e3cf99d7bb13373bf69f38c878953d Mon Sep 17 00:00:00 2001 From: Taddes Date: Tue, 10 Mar 2026 18:13:55 -0400 Subject: [PATCH 1/6] documentation --- docs/src/SUMMARY.md | 1 + docs/src/gh-actions.md | 62 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 docs/src/gh-actions.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 83e7db147a..e7a049a838 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -13,6 +13,7 @@ - [Frequently Asked Questions](faq.md) - [Data Types](data-types.md) - [OpenAPI Documentation](open-api-docs.md) +- [GitHub Actions](gh-actions.md) - [Syncstorage API](syncstorage/api.md) - [API v1.5](syncstorage/api-1.5.md) - [API v1.1 (Obsolete)](syncstorage/api-1.1.md) diff --git a/docs/src/gh-actions.md b/docs/src/gh-actions.md new file mode 100644 index 0000000000..5294fd62be --- /dev/null +++ b/docs/src/gh-actions.md @@ -0,0 +1,62 @@ +# GitHub Actions + +We lint, test, build, and deploy Syncserver-rs using GitHub Actions. We have a number of conventions to follow for security and maintainability purposes and this documentation lays this out. + +For general information on GitHub Actions, please see the [GitHub Actions official documentation](https://docs.github.com/en/actions). + +## Guidelines for Maintaining GitHub Actions + +### Code Review & Approval + +- Require code reviews for all workflow changes; enforce this via branch protection rules and `CODEOWNERS` +- When introducing any new third-party actions, request review from the GitHub Enterprise (GHE) team and Security team. Go to *Github Actions and Applications Security Review Changes* in our internal mana space to submit or speak to a member of the security team. When organization-level requests are made, the GHE team routes them to the Security team for review and approval before granting access. + +The following permission requests are **automatically approved** by the GHE team without a security review: + +- Read-only permissions for all publicly available resources (code, pull requests, issues, etc.) across all public repositories in any Mozilla organization +- Permission removal or decommissioning requests of any kind + +The following require **security review and approval** before access is granted: + +- Read-only permissions for non-public resources (members, teams, settings, etc.) in public repositories +- Read-only permissions for private or internal repositories +- Write permissions for any public, private, or internal repository + +A list of pre-approved apps and actions is maintained in the (GHE Pre-Approved List)[https://github.com/MoCo-GHE-Admin/Approved-GHE-add-ons/blob/main/GitHub_Applications.md]. + +### Action Pinning & Updates + +- Pin all actions to a commit hash instead of a version tag — this applies to Mozilla, GitHub, and especially third-party actions +- Ensure GitHub Actions are kept up to date using [Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot) +- Configure a cooldown period of 7 days for Dependabot updates across all ecosystems. + +### Permissions & Least Privilege + +- Use least privilege for the GitHub token configured in each workflow. +- Avoid 'write' or 'admin' permissions unless absolutely necessary. +- If no specific permissions are required, set `permissions: {}` at the job level. +- Explicitly set `persist-credentials: false` when using the `actions/checkout` action. +- Disable any unnecessary jobs. + +### Injection & Script Safety + +- Review all scripts run in workflows for code injection risk, including both inline and external scripts. +- Pass all parameters to workflows using environment variables — do not use GitHub Actions expressions (`${{ }}`) for this; applies to `github.event.*`, `github.ref_name`, input, and output parameters +- Do not use GitHub Actions expressions for env variables — use `$VARIABLE` instead of `${{ env.VARIABLE }}` + +### Event Trigger Safety + +- Avoid using `pull_request_target` and `workflow_run` event triggers whenever possible +- If these triggers are necessary, target only trusted branches and do not check out untrusted code from the pull request + +### Dependabot Merge Validation + +- When configuring automatic merging or making exceptions for Dependabot, validate the **user** not the actor: + - Use `github.event.pull_request.user.login == 'dependabot[bot]'` + - Do **not** use `github.actor == 'dependabot[bot]'` + +### Secrets & Publishing + +- Use [Trusted Publishing](https://docs.pypi.org/trusted-publishers/) when publishing packages from GitHub Actions +- Do not use caching in sensitive workflows to prevent cache poisoning +- Avoid using `GITHUB_ENV` and `GITHUB_PATH` to pass parameters between steps — use `GITHUB_OUTPUT` instead \ No newline at end of file From 7c77bcfa27afec8604d6253677412c2951aa8ea1 Mon Sep 17 00:00:00 2001 From: Taddes Date: Tue, 10 Mar 2026 18:14:30 -0400 Subject: [PATCH 2/6] update dependabot cadence, add python checks, add actions update for gh actions --- .github/dependabot.yml | 130 ++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 52 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c9785f2a5a..7ff90b65bc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,54 +1,80 @@ version: 2 updates: -- package-ecosystem: cargo - directory: "/" - schedule: - interval: monthly - timezone: UCT - open-pull-requests-limit: 1 - labels: - - dependencies - ignore: - - dependency-name: actix-rt - versions: - - ">= 2.a, < 3" - - dependency-name: protobuf - versions: - - ">= 2.14.a, < 2.15" - - dependency-name: tokio - versions: - - ">= 0.3.a, < 0.4" - - dependency-name: tokio - versions: - - ">= 1.a, < 2" - - dependency-name: futures - versions: - - 0.3.12 - - 0.3.13 - - dependency-name: serde_json - versions: - - 1.0.64 - - dependency-name: hyper - versions: - - 0.14.4 - - dependency-name: url - versions: - - 2.2.1 - - dependency-name: cadence - versions: - - 0.24.0 - - dependency-name: slog-async - versions: - - 2.6.0 - - dependency-name: log - versions: - - 0.4.14 - - dependency-name: serde - versions: - - 1.0.121 - - dependency-name: sha2 - versions: - - 0.9.3 - - dependency-name: slog-scope - versions: - - 4.4.0 + - package-ecosystem: cargo + directory: "/" + schedule: + interval: "weekly" + timezone: UCT + open-pull-requests-limit: 1 + labels: + - dependencies + ignore: + - dependency-name: actix-rt + versions: + - ">= 2.a, < 3" + - dependency-name: protobuf + versions: + - ">= 2.14.a, < 2.15" + - dependency-name: tokio + versions: + - ">= 0.3.a, < 0.4" + - dependency-name: tokio + versions: + - ">= 1.a, < 2" + - dependency-name: futures + versions: + - 0.3.12 + - 0.3.13 + - dependency-name: serde_json + versions: + - 1.0.64 + - dependency-name: hyper + versions: + - 0.14.4 + - dependency-name: url + versions: + - 2.2.1 + - dependency-name: cadence + versions: + - 0.24.0 + - dependency-name: slog-async + versions: + - 2.6.0 + - dependency-name: log + versions: + - 0.4.14 + - dependency-name: serde + versions: + - 1.0.121 + - dependency-name: sha2 + versions: + - 0.9.3 + - dependency-name: slog-scope + versions: + - 4.4.0 + + - package-ecosystem: pip # Applies for poetry deps as well + directories: + - "/" + - "/tools/hawk" + - "/tools/spanner" + - "/tools/postgres" + - "/tools/integration_tests" + - "/tools/syncstorage-loadtest" + - "/tools/tokenserver" + - "/tools/tokenserver/loadtests" + schedule: + interval: "weekly" + timezone: UCT + open-pull-requests-limit: 1 + labels: + - dependencies + + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: "weekly" + timezone: UCT + open-pull-requests-limit: 1 + labels: + - dependencies From 2d72aa52c32b7222fb02b9d2687b54f7eb58b3a9 Mon Sep 17 00:00:00 2001 From: Taddes Date: Tue, 10 Mar 2026 18:29:26 -0400 Subject: [PATCH 3/6] workflow permissions default deny and added per-job permissions --- .github/dependabot.yml | 6 +++--- .github/workflows/checks.yml | 6 ++++++ .github/workflows/glean-probe-scraper.yml | 5 +++++ .github/workflows/mysql.yml | 11 +++++++++++ .github/workflows/postgres.yml | 11 +++++++++++ .github/workflows/spanner.yml | 11 +++++++++++ 6 files changed, 47 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7ff90b65bc..8550781c70 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,6 @@ version: 2 updates: - - package-ecosystem: cargo + - package-ecosystem: "cargo" directory: "/" schedule: interval: "weekly" @@ -53,7 +53,7 @@ updates: versions: - 4.4.0 - - package-ecosystem: pip # Applies for poetry deps as well + - package-ecosystem: "pip" # Applies for poetry deps as well directories: - "/" - "/tools/hawk" @@ -70,7 +70,7 @@ updates: labels: - dependencies - - package-ecosystem: github-actions + - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 7e860514c8..0a8cab432c 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -10,9 +10,13 @@ on: branches: - "**" +permissions: {} # workflow-level default — deny all + jobs: python-checks: runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -30,6 +34,8 @@ jobs: rust-checks: runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: diff --git a/.github/workflows/glean-probe-scraper.yml b/.github/workflows/glean-probe-scraper.yml index 9aa1f7849b..7b2a75241c 100644 --- a/.github/workflows/glean-probe-scraper.yml +++ b/.github/workflows/glean-probe-scraper.yml @@ -5,6 +5,11 @@ on: branches: [master] pull_request: branches: [master] +permissions: {} # workflow-level default — deny all + jobs: glean-probe-scraper: + permissions: + contents: read + checks: write uses: mozilla/probe-scraper/.github/workflows/glean.yaml@main diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml index 5931a017c9..892a910aef 100644 --- a/.github/workflows/mysql.yml +++ b/.github/workflows/mysql.yml @@ -14,9 +14,14 @@ env: RUST_VERSION: "1.91" # RUST_VER PYTHON_VERSION: "3.12" # PY_VER +permissions: {} # workflow-level default — deny all + jobs: build-and-test-mysql: runs-on: ubuntu-latest + permissions: + contents: read + checks: write services: mysql: @@ -134,6 +139,9 @@ jobs: build-mysql-image: runs-on: ubuntu-latest needs: build-and-test-mysql + permissions: + contents: read + actions: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -178,6 +186,9 @@ jobs: mysql-e2e-tests: runs-on: ubuntu-latest needs: build-mysql-image + permissions: + contents: read + checks: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 diff --git a/.github/workflows/postgres.yml b/.github/workflows/postgres.yml index 4c56bd1960..2e408c39e1 100644 --- a/.github/workflows/postgres.yml +++ b/.github/workflows/postgres.yml @@ -14,9 +14,14 @@ env: RUST_VERSION: "1.91" PYTHON_VERSION: "3.12" +permissions: {} # workflow-level default — deny all + jobs: build-and-test-postgres: runs-on: ubuntu-latest + permissions: + contents: read + checks: write services: postgres: @@ -140,6 +145,9 @@ jobs: build-postgres-image: runs-on: ubuntu-latest needs: build-and-test-postgres + permissions: + contents: read + actions: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -184,6 +192,9 @@ jobs: postgres-e2e-tests: runs-on: ubuntu-latest needs: build-postgres-image + permissions: + contents: read + checks: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 diff --git a/.github/workflows/spanner.yml b/.github/workflows/spanner.yml index 8fae1155ed..e5151f652e 100644 --- a/.github/workflows/spanner.yml +++ b/.github/workflows/spanner.yml @@ -14,9 +14,14 @@ env: RUST_VERSION: "1.91" # RUST_VER PYTHON_VERSION: "3.12" # PY_VER +permissions: {} # workflow-level default — deny all + jobs: build-and-test-spanner: runs-on: ubuntu-latest + permissions: + contents: read + checks: write services: spanner-emulator: @@ -168,6 +173,9 @@ jobs: build-spanner-image: runs-on: ubuntu-latest needs: build-and-test-spanner + permissions: + contents: read + actions: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -212,6 +220,9 @@ jobs: spanner-e2e-tests: runs-on: ubuntu-latest needs: build-spanner-image + permissions: + contents: read + checks: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 From 7c07c1ce2e261a7073fe9c7ad0f79cc0dc3fc9e8 Mon Sep 17 00:00:00 2001 From: Taddes Date: Wed, 11 Mar 2026 11:58:11 -0400 Subject: [PATCH 4/6] postgres env var update --- .github/workflows/postgres.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/postgres.yml b/.github/workflows/postgres.yml index 2e408c39e1..a6ca310a0b 100644 --- a/.github/workflows/postgres.yml +++ b/.github/workflows/postgres.yml @@ -95,7 +95,7 @@ jobs: working-directory: tools/postgres run: | poetry install --no-interaction --no-ansi - poetry run pytest test_purge_ttl.py -v --junit-xml="../../workflow/test-results/${{ github.run_number }}-${{ github.job }}-utils_tests.xml" + poetry run pytest test_purge_ttl.py -v --junit-xml="../../workflow/test-results/${GITHUB_RUN_NUMBER}-${GITHUB_JOB}-utils_tests.xml" env: SYNC_SYNCSTORAGE__DATABASE_URL: postgresql://test:test@127.0.0.1/syncstorage From 63b5b92315de180d9fa87ccfddadad84b5beecd2 Mon Sep 17 00:00:00 2001 From: Taddes Date: Wed, 11 Mar 2026 12:01:36 -0400 Subject: [PATCH 5/6] glean commit hash version --- .github/workflows/glean-probe-scraper.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/glean-probe-scraper.yml b/.github/workflows/glean-probe-scraper.yml index 7b2a75241c..49fdccb2b0 100644 --- a/.github/workflows/glean-probe-scraper.yml +++ b/.github/workflows/glean-probe-scraper.yml @@ -12,4 +12,4 @@ jobs: permissions: contents: read checks: write - uses: mozilla/probe-scraper/.github/workflows/glean.yaml@main + uses: mozilla/probe-scraper/.github/workflows/glean.yaml@6cb549542a9d81fddbbaa8d5e6fdf95bf4761488 # v1.0 From 6118a59209519002c1e397bfdef765c6a17d37e2 Mon Sep 17 00:00:00 2001 From: Taddes Date: Wed, 11 Mar 2026 18:14:14 -0400 Subject: [PATCH 6/6] UTC typo --- .github/dependabot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8550781c70..967f9de21e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,7 +4,7 @@ updates: directory: "/" schedule: interval: "weekly" - timezone: UCT + timezone: UTC open-pull-requests-limit: 1 labels: - dependencies @@ -65,7 +65,7 @@ updates: - "/tools/tokenserver/loadtests" schedule: interval: "weekly" - timezone: UCT + timezone: UTC open-pull-requests-limit: 1 labels: - dependencies @@ -74,7 +74,7 @@ updates: directory: "/" schedule: interval: "weekly" - timezone: UCT + timezone: UTC open-pull-requests-limit: 1 labels: - dependencies