aicert.study
Study Track/Security lives outside the prompt

Security lives outside the prompt

90 min

We recommend seeing first: MCP decouples capability from host

Lesson objectives

  • Never rely on prompt instructions to protect a secret
  • Apply least privilege to tools, MCP, and Claude Code permissions
  • Choose between Read, Write, Edit, Bash, Grep, and Glob based on risk boundaries

The problem

A development team writes the following prompt instruction in their project CLAUDE.md: "never print the contents of .env files or include API keys in your responses." It seems like a reasonable safeguard. But it is a defense that lives entirely within prompt text — and a prompt instruction is not an access control boundary. If the model inspects a .env file during a legitimate debugging task (such as verifying why an environment variable is not loading), the secret has already entered the context window token stream. From that moment on, preventing secret leakage depends entirely on probabilistic adherence — zero deterministic security guarantees have been established.

This lesson explores the fundamental distinction between systems that are truly secure and systems that merely look secure: real security lives outside the prompt, enforced via deterministic access controls, least-privilege scoping, and permission boundaries that do not depend on the model "behaving well."

Secrets are never protected by prompt instructions

The architectural rule is simple to state, yet routinely violated under delivery pressure: a secret (API keys, OAuth tokens, passwords, database connection strings) must never be accessible to any runtime process that could emit it in an output payload unless strictly required. The true defenses are structural:

  • Secrets reside in environment variables or dedicated secret management vaults, never hardcoded in source code or versioned configurations.
  • Filesystem inspection tools are explicitly restricted from traversing secret paths (.env, private SSH keys, TLS certificates) when tasks do not require them.
  • When an agent must authenticate an outbound API call, secrets are injected by the execution harness outside the model's reasoning loop — the model decides that a specific API call should occur, the harness resolves and injects the credential headers, and the model never views the raw secret value in its token context.

A directive in CLAUDE.md asking the model not to leak credentials reduces accidental disclosure in standard cases. It is not, and must never be treated as, an architectural security control.

Least privilege across tools, MCP, and Claude Code

The principle of least privilege — granting each system component strictly the minimum permissions necessary to perform its task — applies across three critical layers:

  • Claude Code tools: A custom command or Skill that only parses files should never have Bash enabled. A utility that formats text should not possess Write permissions outside its designated target directory.
  • MCP servers: An MCP server providing read-only access to a database should never expose write or mutation tools unless mutating state is an explicit, audited requirement.
  • Claude Code permissions: Project settings.json configurations should explicitly deny high-risk shell commands (such as rm -rf or git push --force) regardless of what prompt instructions state — enforcing in configuration what cannot rely on probabilistic compliance.

The most prevalent architectural antipattern is granting overly broad permissions "so development doesn't get blocked later." Granting unneeded permissions inflates the blast radius of any model reasoning failure without providing present utility.

Built-in tools carry distinct risk profiles

Claude Code's built-in tools exhibit fundamentally different risk boundaries. Choosing between them is not about finding any tool that "works" — multiple tools can accomplish a given task — but selecting the tool with the smallest possible blast radius:

  • Read: Safe for non-destructive inspection prior to modifying target files.
  • Edit: Requires exact string matching against target blocks; full-file replacements (Write) should be reserved only when structured replacement is demonstrably safer than targeted diffs.
  • Grep: Searches content within files with low operational risk.
  • Glob: Identifies filesystem paths matching patterns without reading file contents into context.
  • Bash: Crosses a broad execution boundary with immense operational power, requiring strict parameter validation, permission controls, and sandbox isolation.

Selecting Bash for a search task that Grep or Read solves natively is not just inefficient — it unnecessarily expands the system attack surface.

Put it into practice

In this lesson's lab, you will implement a permission boundary auditor: given an allowlist of tools for a command or subagent, the script flags least-privilege violations (such as Bash enabled on a read-only task) and simulates out-of-band secret injection where credentials authenticate external APIs without ever surfacing in the model's context stream.

Hands-on lab

Clone the repository and run it locally:

git clone https://github.com/aicertstudy/labs
cd labs/ccar-f/lessons/13-application-security-and-secrets
View folder on GitHub

Ready to test it for real?

Take the full CCAR-F mock exam, in the same format as the official test.

See mock exams

Lesson checkpoint

Loading quiz...