I am building a content pipeline that uses tightly scoped GitHub Apps, one per role, each granted the minimum permissions for its job. When I stood up an App whose only purpose is to write issues and comments, I was surprised that the safe-outputs job also requires contents: read, that is, read access to repository files.
I prefer to document a rationale for every permission an App holds. An issue-writer App that also reads repository content is exactly the kind of grant I would question in security review. If I create a GitHub App for writing issues and then have to arbitrarily add read-content permission, I need a clear justification I can record and defend. So before I grant it, I want to either right-size the permission or understand the rationale well enough to document it.
What prompted this
create-issue and add-comment surfaced it first, since my pipeline uses both. But reading the handlers, contents: read looks like a near-universal baseline: it is requested by nearly every safe-output handler (issue, comment, label, assignment, update, and so on), with only a few explicit exceptions (for example dispatch-workflow, which the spec notes requires only actions: write). So this reads as a systemic baseline rather than a per-handler requirement, and I would like to understand it at that level.
Spec language
The spec lists, for create_issue and add_comment:
contents: read - Repository metadata and file access
and notes:
The contents: read permission is always included for repository context access.
(Most other handlers in section 7.3 describe the same scope slightly differently, as "contents: read - Repository metadata and context", which adds to my uncertainty about what the scope is actually for.)
Questions
-
Metadata versus contents. A GitHub App installation already has metadata: read by default, and the GitHub Actions permissions model exposes repository metadata implicitly (it has no metadata scope). If the requirement is repository metadata, why request the broader contents: read instead of relying on the always-present metadata access?
-
File access on the output path. For output-only handlers like create-issue and add-comment, the consolidated safe_outputs job downloads the agent NDJSON artifact and calls the GitHub API. It does not appear to check out the repository. What file content does the output path actually read? My mental model is that repository file reads belong to the input side (the agent job checkout), not the output side.
Ask
If contents: read is a uniform least-privilege baseline shared across handlers rather than a functional requirement for output-only handlers, could that be documented so operators scoping minimal Apps can justify it in security review, and could output-only handlers omit it where it is not needed? Happy to be told I am missing a real dependency.
If it's not actually needed, it would be amazing to strike it from the permissions requested altogether for those specific outputs.
References
I am building a content pipeline that uses tightly scoped GitHub Apps, one per role, each granted the minimum permissions for its job. When I stood up an App whose only purpose is to write issues and comments, I was surprised that the safe-outputs job also requires
contents: read, that is, read access to repository files.I prefer to document a rationale for every permission an App holds. An issue-writer App that also reads repository content is exactly the kind of grant I would question in security review. If I create a GitHub App for writing issues and then have to arbitrarily add read-content permission, I need a clear justification I can record and defend. So before I grant it, I want to either right-size the permission or understand the rationale well enough to document it.
What prompted this
create-issueandadd-commentsurfaced it first, since my pipeline uses both. But reading the handlers,contents: readlooks like a near-universal baseline: it is requested by nearly every safe-output handler (issue, comment, label, assignment, update, and so on), with only a few explicit exceptions (for exampledispatch-workflow, which the spec notes requires onlyactions: write). So this reads as a systemic baseline rather than a per-handler requirement, and I would like to understand it at that level.Spec language
The spec lists, for
create_issueandadd_comment:and notes:
(Most other handlers in section 7.3 describe the same scope slightly differently, as "
contents: read- Repository metadata and context", which adds to my uncertainty about what the scope is actually for.)Questions
Metadata versus contents. A GitHub App installation already has
metadata: readby default, and the GitHub Actions permissions model exposes repository metadata implicitly (it has nometadatascope). If the requirement is repository metadata, why request the broadercontents: readinstead of relying on the always-present metadata access?File access on the output path. For output-only handlers like
create-issueandadd-comment, the consolidatedsafe_outputsjob downloads the agent NDJSON artifact and calls the GitHub API. It does not appear to check out the repository. What file content does the output path actually read? My mental model is that repository file reads belong to the input side (the agent job checkout), not the output side.Ask
If
contents: readis a uniform least-privilege baseline shared across handlers rather than a functional requirement for output-only handlers, could that be documented so operators scoping minimal Apps can justify it in security review, and could output-only handlers omit it where it is not needed? Happy to be told I am missing a real dependency.If it's not actually needed, it would be amazing to strike it from the permissions requested altogether for those specific outputs.
References
create_issueadd_commentadd_labels(uses the "Repository metadata and context" wording)docs/src/content/docs/specs/safe-outputs-specification.md