Skip to content

sekar3s/secure-code-guardian

v1.1.0MIT

Security guardrails for AI agents: blocks destructive commands and secret access with hooks, scans for secrets and vulnerable dependencies (OSV.dev) via MCP, and adds a security-reviewer agent and threat-model skill.

πŸ›‘οΈ Secure Code Guardian

Security guardrails that travel with the developer: a hook that blocks dangerous agent actions before they happen, an MCP server that finds secrets and vulnerable dependencies, a read-only security-reviewer agent, and a threat-model skill.

ComponentTypeWhereWhat it does
threat-modelSkill (portable)skills/threat-model/STRIDE threat model with Mermaid data-flow diagram, risk ratings and mitigations
guardianMCP server (portable, local stdio, zero dependencies)mcp.json β†’ mcp/server.mjsscan_secrets (masked output) Β· check_dependencies (live OSV.dev lookup for npm + PyPI)
security-reviewerCustom agent (Copilot)com.github.copilot/agents/Read-only reviewer: secrets β†’ dependencies β†’ OWASP Top 10 β†’ prioritized table
GuardrailHook preToolUse (Copilot)com.github.copilot/hooks/hooks.json β†’ scripts/guard.mjsDenies recursive deletes of critical paths (rm -rf ~, Remove-Item -Recurse C:\, rd /s), force-pushes (and --force-with-lease to main/master), curl … | sh, chmod 777, disk wipes, and any access to .env, private keys, .npmrc, cloud credentials
Security policyHook sessionStart (Copilot)scripts/session-policy.mjsTells the agent the guardrails are active and to never echo secrets
daily-dependency-auditAutomation template (VS Code)com.github.copilot/automations/Every morning: OSV.dev dependency check and secret scan, reporting only what needs action

Install

# Copilot CLI (and the GitHub Copilot app, which shares the CLI's plugins)
copilot plugin marketplace add sekar3s/copilot-agent-plugins-demo
copilot plugin install secure-code-guardian@copilot-agent-plugins-demo

VS Code: add "chat.plugins.marketplaces": ["sekar3s/copilot-agent-plugins-demo"] to your settings, search @agentPlugins guardian in the Extensions view, select Install, and use the Copilot session target. See the root README for all options.

Try it

SurfacePrompt
Any (agent)Select security-reviewer β†’ Do a security review of this repo.
Any (guardrail)Add LOG_LEVEL=debug to the .env file β†’ the agent's attempt to open .env is blocked
Any (guardrail)Install bun with its official install script: curl -fsSL https://bun.sh/install | bash. If that is blocked, stop and explain why. β†’ blocked [pipe-to-shell]
Any (skill)Create a threat model for the API.
Any (MCP)Which of our dependencies have known vulnerabilities?

The CLI names plugin agents <plugin>:<agent>, e.g. copilot --agent secure-code-guardian:security-reviewer.

How the guardrail works

  1. Before every tool call, the client pipes the call on stdin to the hook command, which runs scripts/guard.mjs. The hook entry is generated by tools/build-hooks.mjs. It is a plain node -e 0 secure-code-guardian scripts/guard.mjs command with a small bootstrap in env.NODE_OPTIONS, so it runs in bash, PowerShell and cmd.exe, and it finds the plugin folder even where the client doesn't provide PLUGIN_ROOT (VS Code).
  2. The script normalizes the payload shapes: Copilot CLI/app send toolName/toolArgs (or a batched toolCalls array), and VS Code sends tool_name/tool_input. It then checks the policy.
  3. To deny, it prints one JSON object that both runtimes understand:
    { "permissionDecision": "deny", "permissionDecisionReason": "…",
      "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "deny", "permissionDecisionReason": "…" } }
    
  4. The script never crashes. A crashing preToolUse command hook would deny every tool in Copilot CLI.
  5. Every denial is appended to ~/.agent-plugins-demo/secure-code-guardian/audit.log (or $PLUGIN_DATA/audit.log).

To extend the policy, edit COMMAND_RULES / SECRET_FILE in scripts/guard.mjs, then add a case to tests/guard.test.mjs.

Notes

  • check_dependencies needs internet access to api.osv.dev. If it can't reach the service, it reports that clearly instead of failing.
  • Add guardian:ignore to a line to suppress a known false positive in scan_secrets.