All skills
bitwarden avatar

/perform-security-review

@44659bd official
by bitwardenbitwarden/ai-plugins155 stars
20

Performs a security-focused code review by launching multiple specialized agents and a verification agent to ensure comprehensive coverage and accurate findings. Use this skill when the user asks for a "perform-security-review", "bitwarden-security-review", "execute a security review", "run a comprehensive security audit", "perform an end-to-end security assessment", or needs to coordinate multiple security checks across code, dependencies, secrets, and configurations. The skill manages the workflow, delegates tasks to specialized agents, and presents final findings to the user.

Use this Skill: https://skilld.dev/gh/bitwarden/ai-plugins/perform-security-review

This session only. Nothing lands on disk.

referencestool-grants.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Why the Tool Grants Look Like That

Background for the allowed-tools block and step 1-C of perform-security-review. The operative rules are in SKILL.md; this file holds the reasoning.

A * in a Bash rule absorbs whole flags

This is the fact everything below rests on, and it is easy to get wrong. A rule containing * is compiled to an anchored regular expression with each * replaced by .* under the s flag. .* therefore spans spaces, quotes, and entire arguments — it does not stop at a path separator, a word boundary, or a closing quote.

So a rule cannot pin "this argument is the endpoint and nothing else may follow." Wherever a * appears, an attacker-influenced command can insert flags into it and satisfy the literal part of the pattern from inside a later argument.

Concretely, this rule looks endpoint-scoped and is not:

Bash(gh api --method GET -H "X-GitHub-Api-Version: 2026-03-10" "repos/*/*/code-scanning/alerts?*)

It compiles to:

^gh api --method GET -H "X-GitHub-Api-Version: 2026-03-10" "repos/.*/.*/code-scanning/alerts\?.*$

and matches all of these:

command effect
gh api --method GET -H "…" "repos/O/R/code-scanning/alerts?state=open" --jq '.[]' intended
gh api --method GET -H "…" "repos/O/R" -X DELETE --jq '"/code-scanning/alerts?y"' DELETE /repos/O/R
gh api --method GET -H "…" "repos/O/R" --method DELETE --template '{{.}}/code-scanning/alerts?z' DELETE /repos/O/R

The second * swallows R" -X DELETE --jq '", and the required literal code-scanning/alerts? is satisfied inside the --jq program. gh resolves --method and -X last-wins, so the request that goes out is a DELETE — and DELETE /repos/{owner}/{repo} deletes the repository.

So gh api is not granted at all

There is no gh api rule in allowed-tools. No pattern could be written that constrains the verb, and this skill's entire input is a diff an attacker may have influenced, so a rule the model is merely asked to follow is not a control. Step 1-C's two gh api scan-evidence calls (secret scanning and Dependabot) therefore prompt, and in CI they are denied. Step 1-C's Aikido call does not go through gh api, so it is unaffected.

That is a real capability loss: GHAS evidence is unavailable on the unattended path unless the deployment grants it. The control at that level is the token, not a permission rule — run the workflow with a read-only GH_TOKEN and minimal permissions:, and the destructive verb is unavailable no matter what command is composed. A deployment that has done that can add its own narrow allow rules with the residual risk understood.

Step 1-C is written to degrade rather than fail: each scanner records its own outcome, and for the two gh api scanners a denial is recorded as Not checked (permission denied) so it never reads as None, which would say the scanner ran and found nothing. Aikido cannot reach that state — its grant is pre-approved, so the call never prompts and is never denied.

Why the default-branch lookup does not use gh api

The endpoint that answers it is repos/{owner}/{repo}, whose DELETE deletes the repository, so candidate 2 uses gh repo view --json defaultBranchRef instead. gh repo view has no --method or -X flag at all, so the last-wins problem cannot arise. This is the general shape of the fix: prefer a subcommand that cannot express the dangerous operation over a rule that tries to forbid it.

Why the rm grant went too

Bash(rm -f /tmp/security-review-*) was kept at first on the reasoning that a cleanup step is lower stakes than an API call. That reasoning was wrong in the same way the gh api rules were: the .* absorbs flags, not just path characters, so rm -f /tmp/security-review-x -rf <any-path> matches the rule and is a recursive tree delete. The identifiers are chosen per run, so no literal rule can enumerate them. The grant is gone. Step 7 clears the diff with the granted Write tool instead, which is the better answer anyway: it removes the content without needing a shell at all, and it runs unattended. The file stays on disk, empty.

Why the git grants stay

Bash(git diff:*) and Bash(git log:*) both accept --output=<file>, verified, so a prefix rule over either is an arbitrary-file-write primitive. They are kept anyway, and the reason is specific rather than general: this skill already holds Write, so the capability adds nothing an attacker-steered run could not already do. Removing them would cost the skill its diff and leave the exposure unchanged. That argument does not extend to a grant whose flag reaches a capability the skill lacks — which is exactly why gh api and rm went.

Bash(git branch --show-current:*) is not in the same class. git branch --show-current -D <br> is a usage error and deletes nothing, so the prefix does not admit branch deletion.

Every future grant here should be reasoned about the same way: by what an inserted flag can do inside each *, never by how specific the pattern looks.

Source: SKILL.md on GitHub

1 warning14d3 checks · Risk SAFE
  • Gen Agent Trust Hub14d

    This skill coordinates a security code review by delegating tasks to specialized sub-agents. It includes instructions to bypass safety filters for the purpose of the audit and processes untrusted external data (git diffs), which presents a surface for indirect prompt injection.

  • Socket14d

    No alerts

  • Snyk14d

    Risk: MEDIUM · 1 issue

Signed by skilld at 44659bd. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 2 weeks ago
What it can do
Runs commands Reads files Edits files
MCP servers
plugin_aikido_aikido-mcp
All 15 allowed tools
Bash(gh pr diff:*)Bash(gh pr view:*)Bash(gh repo view --json defaultBranchRef:*)Bash(git branch --show-current:*)Bash(git diff:*)Bash(git log:*)Bash(git merge-base:*)Bash(git remote get-url:*)Bash(git rev-parse:*)Bash(printenv GITHUB_ACTIONS)ReadSkillTaskWritemcp__plugin_aikido_aikido-mcp__aikido_issues_list
Other metadata
argument-hint
[--output <chat|file|github>] [--output-dir <path>] [--model <model>] [--base-ref <ref>] [pr-number-or-url|commit-sha|duration]
  • security-review
  • code-review
  • vulnerability-assessment
  • bitwarden
  • multi-agent
  • github
  • secrets
  • dependencies
  • architecture
  • threat-modeling

README badge

README badge for bitwarden/ai-plugins/perform-security-review

Orchestrates a multi-agent security code review by delegating to specialized agents covering injection flaws and OWASP top risks, secrets and dependencies, security architecture and zero-knowledge invariant compliance, and threat modeling. Fetches GitHub scan evidence (code scanning, secret scanning, Dependabot) upfront and routes the diff and findings through a verification agent for triage and confidence rating before generating a classified report.

Generated from the current SKILL.md.

What security domains does this skill cover?
The skill coordinates four specialized agents covering code security (injection flaws, cryptography, OWASP A01-A05), secrets and dependencies (hardcoded credentials, vulnerable packages), security architecture (auth, encryption, zero-knowledge invariant), and threat perspective (data flows, privilege escalation, API abuse).
Can this skill review a GitHub PR, commit, or local changes?
Yes. The skill supports PR mode (PR number or URL), commit mode (commit SHA), time-based mode (duration like "last 48 hours"), local changes mode (unstaged/staged diffs), and branch comparison mode (current branch vs main).
Does this skill fetch GitHub Advanced Security scan results?
Yes. It pre-fetches code scanning, secret scanning, and Dependabot alerts from GitHub, then includes that evidence in agent prompts to triangulate and verify findings.
What output formats are supported?
The skill supports chat (inline), file (saved to disk with `--output-dir` option), and GitHub (posting results as a comment or check, if integrated).
Does this skill verify findings after the four agents report?
Yes. A fifth verification agent reviews all findings, applies the security-review-rubric severity/confidence matrix, and classifies each as Blocker, Improvement, Note, Strength, or Dismiss — but does not remove or introduce findings.

Generated from the current SKILL.md. These answers refresh after source changes.