Skip to content

[IDP-1735] Add dd-octo-sts trust policy for Publishing Platform - #3190

Closed
bgoldberg122 wants to merge 1 commit into
masterfrom
bgoldberg122/idp-1735-octo-sts-trust-policy
Closed

bgoldberg122 wants to merge 1 commit into
masterfrom
bgoldberg122/idp-1735-octo-sts-trust-policy

Conversation

@bgoldberg122

@bgoldberg122 bgoldberg122 commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

What

Adds .github/chainguard/pub-platform.publish.prod.sts.yaml, a dd-octo-sts trust policy letting the Datadog Publishing Platform services mint short-lived, repo-scoped GitHub installation tokens for this repository.

One new file. No existing file is modified. Jira: IDP-1735.

Why

Publishing Platform authenticates to GitHub today with a long-lived GitHub App private key read from Vault (k8s/rapid-assets/pub-platform-internal/pub-plat-github) — see config.py and the Auth.AppAuth(...) call sites in services/github_pr.py. dd-octo-sts replaces that with 1-hour tokens minted per exchange against an OIDC identity, so there is no durable credential to leak or rotate.

This repo's role: one of Publishing Platform's integration_repos — the services open and update integration-listing PRs against it.

The calling services:

Safe to merge now — and merging is a prerequisite

This is additive and inert. A trust policy grants nothing by itself: a token is only ever issued if (a) this policy is present on the default branch, and (b) the calling identity is in the central dd-octo-sts allowlist. Nothing calls the exchange for this repo until the application cutover ships, so merging this changes no behaviour today.

It does need to merge, though: this policy being on the default branch is a hard prerequisite for the cutover. dd-octo-sts reads trust policies from the default branch only, so a policy sitting in an unmerged PR is invisible. It is opened as a draft because the reviewable question is the permission set, not the timing — please convert and merge whenever the scope below looks right to you.

Permissions, and why each one

permission why
contents: write The write path creates blobs, trees, commits and refs, edits a branch head, deletes refs, and squash-merges. Calls: create_git_blob, create_git_tree, create_git_ref, get_git_tree, get_branch, branch.edit, ref.delete, merge.
pull_requests: write create_pull, get_pulls, get_pull, and the squash merge.
metadata: read Implied baseline for the above.

Deliberately not requested:

  • checks — APW check polling (_get_branch_and_apw_check_status) is only ever called with pub_platform_repo, the shadow repo. This repo never has its checks read, so it gets no checks grant. Only one of the six target repos does.
  • any review, label, issue, workflow or team scope — nothing in the code path uses them. Team lookups go through the Datadog OUI client (team_utils.py), not GitHub.

I derived this from a full inventory of every GitHub call in github_pr.py rather than copying a template. The subject_pattern is an anchored alternation over exactly the identity/datacenter pairs each service is actually placed in per its rapid.json release.placement — it does not glob the datacenter.

Why the sycamore issuer

The supported Python route to an ID token is dd_internal_authentication's JWTInternalServiceAuthClientTokenManager with issuer="sycamore", which mints a Ticino token whose identifying claim is the email-shaped <namespace>.<service>@kubernetes.<datacenter>. The legacy per-datacenter Vault issuers (and their opaque UUID subjects, as in openvex-worker-ghsa-prod.sts.yaml) would never match a token minted this way. This matches every existing Python dd-octo-sts consumer, e.g. pipeline_ai, and the shape of airflow-ai-guard.false-positive.create-pr.prod.sts.yaml.

Dependencies

  • Allowlist: ddoghq/dd-source#111800 adds these identities to the central dd-octo-sts allowlist. It needs #sdlc-security review and is the wall-clock long pole for the whole migration.
  • Code cutover: sequenced after IDP-1727 and IDP-1728, which are actively rewriting the same auth/config surface (config.py, GITHUB_AUTH_CONFIG.md). This PR touches neither, so it is independent of their ordering.
  • App installation: the dd-octo-sts GitHub App must be installed on this repo before the first exchange succeeds.
  • One caveat for cutover planning, not for this PR: dd-octo-sts mints tokens from the dd-octo-sts App's installations, not Publishing Platform's app. The GitHub actor on branches, commits and PRs therefore changes, which matters for anything keyed on the current app as PR author (CODEOWNERS/ruleset bypass allowances, auto-approval).

Test plan

  • dd-octo-sts check against this repo once both this PR and the allowlist PR have merged, confirming the policy and allowlist agree before any code change
  • staging end-to-end publish against pub-platform-staging (its own policy PR) ahead of any prod cutover

🤖 Generated with Claude Code

Publishing Platform authenticates to GitHub with a GitHub App private key
read from Vault. This trust policy lets the pub_platform and
pub_platform_internal services mint short-lived dd-octo-sts installation
tokens for this repo instead, scoped to the minimum permissions their
GitHub write path actually uses.

Additive: it grants nothing until the services are cut over, and the
identities are separately allowlisted in dd-source.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dd-octo-sts

dd-octo-sts Bot commented Sep 29, 2026

Copy link
Copy Markdown

Validation Report

All 11 validations passed.

Show details
Validation Description Status
ci Validate CI configuration and code coverage settings ✅
codeowners Validate every integration has a CODEOWNERS entry ✅
config Validate default configuration files against spec.yaml ✅
imports Validate check imports do not use deprecated modules ✅
integration-style Validate check code style conventions ✅
jmx-metrics Validate JMX metrics definition files and config ✅
legacy-signature Validate no integration uses the legacy Agent check signature ✅
metadata Validate metadata.csv metric definitions ✅
models Validate configuration data models match spec.yaml ✅
package Validate Python package metadata and naming ✅
readmes Validate README files have required sections ✅

View full run

@bgoldberg122

Copy link
Copy Markdown
Collaborator Author

Closing unmerged — IDP-1735 has been deprioritized.

All findings from this work (the sycamore-vs-Vault issuer correction, the Python support verdict, the egress gap, and the full Phase B plan) are recorded on the Jira card: https://datadoghq.atlassian.net/browse/IDP-1735

The branch is left in place, so this PR can be reopened as-is when the card is picked back up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant