Announcing Beacon: Self-improving memory for coding agents
← All skills
Skill

create-github-pr

skill:nvidia/openshell#create-github-pr

Create GitHub pull requests using the gh CLI. Use when the user wants to create a new PR, submit code for review, or open a pull request. Trigger keywords - create PR, pull request, new PR, submit for review, code review.

Verdict
Suspicious

Risky behavior the analysis could not rule out.

Analyzed Oct 27, 2026, 22:33 UTC at fa2d381

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

6
findings
high
highest severity
4
threat classes
2,140
files scanned
225/225
checks satisfied
0
package advisories

Why this verdict

  • suspicious: finding skill:.agents/skills/create-github-pr:.agents/skills/create-github-pr/SKILL.md:37:PRIVESC
  • suspicious: finding skill:.agents/skills/create-github-pr:.agents/skills/create-github-pr/SKILL.md:51:EXEC
  • suspicious: finding skill:.agents/skills/create-github-pr:.agents/skills/create-github-pr/SKILL.md:51:HIJACK
  • suspicious: finding skill:.agents/skills/create-github-pr:docs/how-it-works/gateways/configuration.mdx:1471:SUPPLY
  • suspicious: finding skill:.agents/skills/create-github-pr:docs/how-it-works/gateways/configuration.mdx:799:SUPPLY
  • suspicious: finding skill:.agents/skills/create-github-pr:docs/how-it-works/sandboxes/runtimes.mdx:171:PRIVESC

Security findings 6

Code execution

highContextual risklow confidence

The skill instructs the agent to run the sync-agent-infra skill's full consistency check whenever a branch adds, removes, or renames skills or crates or changes workflow relationships, and that skill's file is not consumed content, so the agent would execute commands that nobody can review.

Run its full consistency check when the branch adds, removes, or renames skills or crates
trigger:conditionalvector:instruction
Counter-argument considered

The quoted instruction sits verbatim in the agent-facing skill body and directs execution of the sync-agent-infra skill's consistency check, whose content the follow-up confirms lies outside the consumed set; no carve-out, declared claim, or mitigation covers this hand-off, and the file's in-repository existence or NOT CONSUMED status cannot make the instruction harmless, declared, or chain-free, so the contextual-risk finding stands.

Privilege escalation

mediumContextual riskmedium confidence

The create-github-pr skill instructs the agent to retry failed gh network lookups from outside the sandbox, evading sandbox network isolation to reach GitHub; this sandbox-escape instruction is undeclared in the skill's PR-creation purpose.

retry sandbox network failures outside the sandbox before
vector:instruction
Counter-argument considered

The skill explicitly instructs the agent to retry failed gh network lookups from outside the sandbox on the mandatory pre-PR verification path, evading sandbox network isolation; this escape instruction is not part of the declared PR-creation capability and is a concrete agent directive, so the finding stands.

Agent hijacking

mediumContextual risklow confidence

The skill directs the agent to load and run the unshown sync-agent-infra skill's maintenance map and full consistency check, causing the agent to apply instruction content this artifact does not ship; the loaded content's behavior is unknowable from this evidence.

Run its full consistency check when the branch adds, removes, or renames skills or crates
vector:instruction
Counter-argument considered

The skill openly delegates the agent to another skill's maintenance map and full consistency check, content this target does not ship; the follow-up shows that content is outside every consumed skill set, which under the rules never neutralizes the instruction, and no declared claim covers delegating execution to it, so the finding survives as a contextual risk.

Supply chain

mediumContextual risklow confidence

The Podman driver documentation presents proxy.corp.com, a hostname under a publicly registrable domain rather than a reserved example TLD (unlike the proxy.corp.example used elsewhere in the same file), as the example corporate-proxy endpoint, which would route sandbox egress and, per the surrounding warning text, Basic proxy credentials to that third-party host if the example is copied verbatim.

http://proxy.corp.com:8080
vector:instruction
Counter-argument considered

proxy.corp.com sits under a publicly registrable TLD while the same file uses the reserved proxy.corp.example elsewhere, and the surrounding warning confirms Basic credentials are sent to the configured http:// proxy, so a verbatim copy of the example diverts sandbox egress and cleartext credentials to a third-party host; the claim matches the evidence and no carve-out or mitigation neutralizes it.

Supply chain

lowContextual riskmedium confidence

The artifact declared as a 'create GitHub pull requests using the gh CLI' skill ships only OpenShell gateway and sandbox-runtime documentation across these units (credential drivers, key-encryption-key storage, interceptors, compute drivers, preflight commands) with no gh or pull-request functionality present, so this content is undeclared by and unnecessary for the stated purpose (unexplained, not concealed).

Set `credential_drivers` only when the gateway should store provider secrets in an external credential backend.
Counter-argument considered

I tried to kill this as a benign packaging artifact, but nothing in the shown evidence contradicts the claim: a skill declared solely for gh-CLI pull-request creation ships OpenShell gateway credential-driver, interceptor, admission, and sandbox-runtime documentation that is unrelated to and uncovered by that declaration, and no carve-out or declaring text neutralizes the mismatch. The docs address human operators rather than the agent, so no agent-directed chain exists, which limits severity without refuting.

Privilege escalation

lowContextual risklow confidence

The sandbox documentation instructs operators to enable host bind mounts and disable resource admission, a configuration that exposes gateway-host files to sandbox workloads and bypasses the product's workspace isolation and filesystem policy, with an additional disclosed limitation that libkrun cannot confine a compromised guest kernel to the mounted source directory.

Bind mounts expose gateway-host files to the sandbox and can bypass workspace isolation and filesystem policy.
vector:instruction
Counter-argument considered

The artifact's own text confirms the claimed behavior: bind mounts are documented as requiring enable_bind_mounts and disabled resource admission while exposing host files and bypassing isolation, and libkrun is admitted not to confine a compromised guest, with nothing in the gh-CLI declaration covering this content; the prominent warnings are disclosure, which under the rules does not neutralize the finding. Because the text instructs operators, not the agent, no agent-directed chain is shown, lowering severity but not refuting.

Open questions 7

What the analysis could not settle from the code alone.

The skill frontmatter sets metadata.internal=true with no stated consumer; confirm whether this self-applied 'internal' status label changes runtime permissions or suppresses review for the skill.
All PY-CLAIM-CONTRADICTION detector leads were checked against the cited units: the 'contradicting' evidence is TOML/YAML bracket and punctuation characters (']', '
Does the frontmatter flag metadata.internal: true alter loader trust, permission, or review-gating behavior for this skill in the consuming agent platform? The claim itself is an unverifiable status claim and carries zero weight, but its runtime effect is not determinable from the shown content.
Are the OpenShell gateway/sandbox documentation units in this batch actually part of the declared create-github-pr skill's shipped/consumed content, or unrelated repository files? None of the 32 reviewed units contains any gh-CLI or pull-request functionality, and no undeclared-residue items were extracted, so the intended relationship between declared purpose and shipped content cannot be settled from the evidence shown.
Supply chain
Contradiction leads C28 and C30 (DET:b1be2e26f1daadaa, DET:e6a5d1c0f933c6c0) verify as extractor false positives, not real contradictions: line 314 is an operator-facing shell snippet where 'oc -n openshift-config get cm ... > corp-ca.pem' redirects a CA bundle to a local temp file before creating a configmap, a documented and necessary operator step unrelated to sandbox mounts; line 300's '/*' comes from '<domain>/*' wildcards in the allowed_pod_annotations table row, an annotation-key pattern,⟦… 273 more chars …⟧
The target is declared as a GitHub pull-request skill (gh CLI), but all four units in this batch are OpenShell sandbox runtime documentation (docs/how-it-works/sandboxes/runtimes.mdx) with claims D190-D203 and contradictions C28/C30 routed to this target; confirm whether this skill actually ships or references this documentation (a purpose mismatch worth flagging) or whether these units belong to a different target in the repository and were batched here in error.
The skill frontmatter carries the unverifiable status claim `metadata.internal: true`; confirm whether the loading system honors it to reduce scrutiny of this skill (it carries no weight either way, and the declared description matches the observed content).
Refuted findings 3

Candidates the review stage examined and rejected, kept for transparency.

Agent hijacking

highRefutedlow confidence

The skill defers vulnerability disclosure and contributor vouching to the unconsumed SECURITY.md and states that the vouch check may close unvouched PRs, extending the agent's behavior beyond PR creation into moderation and policy enforcement that cannot be reviewed.

Follow `SECURITY.md` for vulnerability disclosure. First-time external contributors must be vouched before their PRs are accepted; the vouch check may close unvouched PRs.
Why it was refuted

The quoted text assigns PR-closing to an external vouch check (not the agent) and only directs the agent to consult SECURITY.md for disclosure and check the vouch process before opening a PR; that is policy consultation within the declared PR-creation workflow, openly stated in the skill body, so no harmful or concealed behavior exists and the 'moderation and policy enforcement' claim overstates the quote.

Agent hijacking

highRefutedlow confidence

The create-github-pr skill makes CONTRIBUTING.md binding for branch naming, verification guidance, and issue-acceptance exceptions even though that file is not consumed by any agent or client, so at runtime the agent follows whatever instructions CONTRIBUTING.md then contains.

Follow Branch Names in `CONTRIBUTING.md` for contributor branch names.
Why it was refuted

Every CONTRIBUTING.md reference is scoped to contributor branch names, verification-check selection, and documented issue-acceptance exceptions - consultation intrinsic to the declared create-a-PR capability and openly stated in the skill body - so the open-ended 'whatever CONTRIBUTING.md then contains' hijack framing overstates scoped policy lookups; harm and undeclared fail.

Supply chain

highRefutedlow confidence

The MXC driver documentation instructs readers (and any agent loading this reference) to follow configuration instructions hosted at an unpinned, mutable branch URL on github.com/NVIDIA/OpenShell (tree/windows, blob/windows/WINDOWS.md, blob/windows/docs/...), so the instructions loaded from that reference can change without pinning.

Follow the [Windows configuration guide](https://github.com/NVIDIA/OpenShell/blob/windows/docs/how-it-works/gateways/configuration.mdx#mxc)
Why it was refuted

The link targets the windows-branch edition of this same file (identical path docs/how-it-works/gateways/configuration.mdx) in the same repository that the doc itself designates as the required build source for the MXC driver; the reference is openly stated in the file and stays inside the artifact's own trust boundary, adding no external supply channel, so harm and undeclared fail.

Coverage gaps 42

Parts of the artifact the static analysis could not fully examine.

context:manifest_unparseable yaml: YAML aliases are not permitted
.github/workflows/build-binaries.yml
context:manifest_unparseable yaml: YAML aliases are not permitted
.github/workflows/build-images.yml
context:manifest_unparseable yaml: while parsing a flow node
crates/openshell-prover-cli/tests/fixtures/invalid.yaml
context:manifest_unparseable yaml: YAML aliases are not permitted
deploy/docker/docker-compose.yml
context:manifest_unparseable yaml: while parsing a flow mapping
deploy/helm/openshell/templates/agent-sandbox-preflight.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/backend-tls-policy.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/cert-manager-pki.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/certgen.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/clusterrole.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/clusterrolebinding.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/credential-secrets-namespace.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/credential-secrets-role.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/credential-secrets-rolebinding.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/credential-storage-key-encryption-key-secret.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/deployment.yaml
context:manifest_unparseable yaml: expected '<document start>', but found '<block mapping start>'
deploy/helm/openshell/templates/gateway-config.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/gateway.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/grpcroute.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/hpa.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/networkpolicy.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/peer-role.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/peer-service.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/replica-services.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/role.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/rolebinding.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/route.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/service.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/serviceaccount.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/statefulset.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/supervisor-hpa.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/supervisor-networkpolicy.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/supervisor-pdb.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/supervisor-service.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/supervisor-token-secret.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/supervisor.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/workspace-secret-source-role.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell/templates/workspace-secret-source-rolebinding.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell-workspace/templates/networkpolicy.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell-workspace/templates/role.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell-workspace/templates/rolebinding.yaml
context:manifest_unparseable yaml: while parsing a flow node
deploy/helm/openshell-workspace/templates/serviceaccount.yaml
context:manifest_unparseable yaml: while scanning a simple key
e2e/mcp-conformance/policy-template.yaml