Summary: A repository owner reviewing AI-assisted code needs to notice changes to the machinery that builds and deploys it. A small workflow, dependency or policy edit can alter authority beyond the feature under review. The GitHub Repository Guard integration documents how APort collects protected-path evidence from trusted base policy and can attach signed hosted decisions to repository activity.
GitHub Guard is one part of the review path. A report-only workflow can succeed despite a denial or a sensitive-file finding. Blocking a merge requires an enforcement configuration and a required check. Direct-push workflows observe changes after GitHub accepts them, so branch restrictions remain necessary.
Review the files that define authority
Application tests may pass while a change grants a workflow broader permissions or edits its own policy. Include these surfaces in the repository's review-sensitive path list:
| Surface | Question for the reviewer |
|---|---|
.github/workflows/** | Did token permissions, triggers or release steps change? |
| Package manifests and lockfiles | Did installation or execution behavior change with dependencies? |
.aport/** and other policy files | Is the proposal trying to change the rules used to assess itself? |
| Release and deployment scripts | Can the automation publish or deploy through a new path? |
| Verifier implementation | Does a policy decision retain its intended meaning? |
These are starting points for a repository owner, not a claim that every edit is malicious. Tune the list to the repository and inspect the actual diff.
What a protected path policy does
A protected path marks a file that deserves stronger review when changed. It does not mean that every edit is malicious. For example, a workflow can legitimately gain an OIDC permission while a deployment integration is installed; it can also gain an unrelated repository write permission in the same diff. Review those changes separately.
The evidence should explain who proposed the change, which protected files were touched, whether the patch is complete, and whether the governing policy was itself modified. Keep package manifests, lockfiles, local actions, configuration and release scripts in view as well as application source.
Why GitHub Actions need special handling
The Action source and README document structural findings used during repository review:
| Finding | What the reviewer should inspect |
|---|---|
OAP.REPO.PROTECTED_PATH_TOUCHED | Which protected file changed and whether the touch is warning-level or configured to block |
OAP.GH.POLICY_HEAD_UNTRUSTED | A proposed policy change must not govern its own review |
OAP.REPO.PULL_REQUEST_TARGET_INTRODUCED | New use of a privileged event and what untrusted content it might execute |
OAP.REPO.WORKFLOW_PERMISSION_ESCALATION | Added repository write authority such as contents: write or write-all |
OAP.REPO.OIDC_TOKEN_PERMISSION_ADDED | New ability to request an identity token and the external trust policy that accepts it |
OAP.REPO.SUSPICIOUS_OBFUSCATION | Encoded or remote execution in a sensitive configuration or execution surface |
OAP.REPO.SUSPICIOUS_CONTENT_DIFF_UNAVAILABLE | Missing content needed to inspect a sensitive file |
OAP.REPO.UNPINNED_ACTION | An action not pinned to a full commit SHA when the trusted policy requires pinning |
OAP.REPO.WORKFLOW_DIFF_UNAVAILABLE | A workflow patch the analyzer cannot inspect |
OAP.REPO.EVIDENCE_TRUNCATED | File or commit evidence that is incomplete |
These findings are review evidence with specific triggers. Their absence is not a proof that a workflow has no exploitable behavior. In particular, id-token: write permits OIDC token issuance; it does not itself grant content-write authority. Review the token recipient's trust conditions as well as the GitHub permissions.
Pull requests: attribution and its limits
The Action can read commit trailers linking a change to an agent, decision and session:
APort-Agent: ap_example
APort-Decision: dec_example
APort-Session: sess_exampleThese are illustrative identifiers. Verify the referenced receipt and its context before relying on the link. A trailer is not a signature, and an attribution heuristic is not proof that a human or agent authored every changed line. Missing evidence should remain unattributed rather than acquiring a confident label.
A runtime pre-action receipt can explain why a tool operation was allowed before the commit existed. A CI-time receipt explains repository policy evaluation later. Keep their timing explicit in the audit trail.
Push events need first-class evidence
For a push, the Action uses the GitHub comparison between the event's before and after SHAs to collect files and commits. An unavailable range or truncated response leaves incomplete evidence. A branch creation or an unusable before value also needs deliberate handling; do not invent a complete comparison.
The job can report the push and influence later gates, but the event is already committed. Branch protection, required reviews and bypass permissions determine who can write directly. Test those controls independently of the Action's report.
The backslash path bug that matters more than it looks
A Git repository on a Linux runner can contain a root-level filename with a literal backslash:
src\payload.jsThat is different from the nested path:
src/payload.jsConverting backslashes in evidence into forward slashes would change the meaning of the path and could make a policy such as src/** match the wrong file. The Action preserves literal backslashes in repository paths, while policy patterns can normalize separators for authors. This distinction is covered in its test runner.
The general rule is to normalize policy input deliberately while retaining the identity of the evidence being tested. Review rename and delete cases as well as ordinary modifications when choosing protected paths.
Do not let a proposal supply its own approval policy
For pull requests, the Action fetches .aport/policy.yaml or .aport/policy.yml from the trusted base SHA/ref. For pushes, it uses the pre-push commit when a usable before SHA exists. It does not accept the PR head's changed policy as the authority for that same change.
A policy edit is recorded as OAP.GH.POLICY_HEAD_UNTRUSTED. The policy file controls Action-side report evidence; hosted authorization still goes through the repository policy pack and hosted passport. Keep those responsibilities separate when explaining a finding.
Missing or truncated diff evidence also needs review. A result based on incomplete inputs should not be presented as proof that the unseen content is acceptable.
Install the evidence path, then choose enforcement
The documented initializer is:
npx @aporthq/aport-agent-guardrails githubIt writes the workflow and refuses to overwrite existing files without an explicit force option. The integration guide contains the supported event triggers, permissions and mode settings; use it as the workflow owner rather than copying a partial YAML fragment from a blog.
Ordinary protected-path touches warn by default. The Action README documents a stricter exception for control-plane paths such as existing workflows, local actions and .aport/policy.*: those can fail the check even with block-protected-paths: false. After tuning the list, a repository can opt into mode: hosted with block-protected-paths: true for broader protected-path blocking. Make the check required in branch protection or rulesets if failure must prevent merging. A badge is useful visibility, but it does not impose that requirement.
How to configure a GitHub workflow
The source integration guide includes this complete manual fallback. Adapt the protected branch name to your repository and use your organization's approved Action pinning policy:
name: APort Repository Guard
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled, review_requested, review_request_removed]
pull_request_review:
types: [submitted, dismissed]
push:
branches:
- main
merge_group:
permissions:
id-token: write
contents: read
pull-requests: read
jobs:
aport:
name: APort / OAP code.repository.merge.v1
if: >-
github.event_name != 'pull_request_review' ||
github.event.action == 'dismissed' ||
github.event.review.state != 'commented'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: aporthq/policy-verify-action@v1
with:
mode: autoReview and dismissal events allow review evidence to be refreshed. merge_group supplies a check in a merge queue. OIDC issuance and evidence collection need the listed permissions; no repository content-write permission is added by this example.
The default unmanaged auto path can fall back to labeled evidence-only reporting if hosted setup is unavailable. Explicit hosted mode requires a valid signed decision; managed configuration does not silently fall back. The OIDC guide explains when customer-owned audit adds a scoped secret.
What should block first
Start by distinguishing a warning from an unavailable or adverse authorization result. Tune the repository's rules with allowed changes and deliberately prohibited fixtures, then require the check where merging depends on it. Do not assume every finding listed above has identical severity.
The Action documents a narrow installation exception: a PR that only adds qualifying guard-install workflows can receive a warning for those new control-plane files. It does not apply to editing existing workflows, changing existing policy, direct pushes, pull_request_target, extra run: steps or non-allowlisted actions. When trusted policy requires SHA pinning, leaving an action unpinned removes that exception. Review the exact conditions for the Action version you install.
Before relying on the check, test an existing workflow modification, an ordinary protected file, an incomplete diff and a clean application change. Confirm the expected result for each, then confirm that GitHub's required-check rule blocks an attempted merge on failure. That final check distinguishes a useful report from an enforced repository policy.
Check the paths around the pull request
A push event provides evidence after the change lands. It cannot retroactively prevent the push. Restrict direct writes to protected branches through GitHub's controls, and review who may bypass them.
Untrusted fork PRs also have different credential availability. Follow the documented evidence-only or supported no-secret OIDC behavior; do not use pull_request_target as a shortcut around fork restrictions.
For actions before a commit exists, use a connected runtime hook such as the Claude Code setup. The signed-audit guide explains how to keep policy and execution evidence distinct across both boundaries.
Protect my GitHub repo by starting with one repository's review-sensitive paths and a verified required-check configuration.
Choose the pilot repository and its buying path
Start with one repository whose owner can review protected paths and change branch rules. Record which workflow events the guard checks and what evidence is missing. Keep report-only findings visible during the pilot, then require the enforcement check after validating legitimate and prohibited changes.
GitHub report-only and blocking enforcement do not require a paid plan. Team adds organization audit, shared controls and setup support through the existing organization billing flow. For repository fleets, name a rollout owner and plan an Enterprise cohort with shared policies, exception review and rollback responsibilities.
Product and implementation sources
Choose your rollout path
Team uses organization billing and Stripe Checkout. Enterprise starts with a rollout call to agree the deployment scope.
Install my guardrailFrequently Asked Questions
Common questions about this topic.