Skip to main content

Security

What jaan-to accesses, how it works, and why your data stays safe.


What jaan-to Accesses​

jaan-to is a Claude Code plugin that adds structured workflows (skills) to your development process. Here is exactly what it reads, writes, and executes.

Reads​

WhatWherePurpose
Project configjaan-to/config/settings.yamlCustomize paths, language, features
Context filesjaan-to/context/*.mdProject-specific tech stack, team, boundaries
Project filessrc/, apps/, etc.Analysis only (e.g., detect skills, code review)
Plugin defaultsconfig/defaults.yaml (plugin)Fallback values for settings

Writes​

All generated content goes to project-local directories only:

WhatWhere
Generated outputsjaan-to/outputs/
Accumulated lessonsjaan-to/learn/
Custom templatesjaan-to/templates/
Context filesjaan-to/context/
Metricsjaan-to/metrics/

jaan-to never touches: .env, secrets, credentials, SSH keys, hidden directories outside jaan-to/.

Executes​

Shell scripts from the plugin's scripts/ directory run at specific lifecycle events (see Hooks below). All scripts are:

  • Visible and auditable in scripts/
  • Non-obfuscated plain bash
  • Using set -euo pipefail for safety
  • Cleaning up temp files via trap ... EXIT

Network​

jaan-to makes no network calls by default. The only skills that access the network:

  • pm-research-about — uses WebSearch and WebFetch for public web research
  • jaan-issue-report — uses gh CLI to submit issues to GitHub (with explicit user approval)
  • devops-deploy-activate — uses platform CLIs (gh, vercel, railway, fly) for deployment setup
  • frontend-visual-verify — uses Playwright MCP to navigate localhost-only URLs (default: localhost:*, 127.0.0.1:*). External domains require explicit per-URL user confirmation. Playwright MCP config enforces this via network.allowedOrigins.

Output-only safety note: frontend-component-fix generates patch artifacts under $JAAN_OUTPUTS_DIR only. It does NOT edit project source files directly. Patches are applied through dev-output-integrate which has proper Edit(src/**) permissions and conflict detection.

No telemetry, analytics, or data is sent to jaan-to servers. There are no jaan-to servers.


How Hooks Work​

Hooks are shell scripts that run automatically at specific points in a Claude Code session.

Lifecycle Events​

EventWhenWhat Runs
SessionStartSession beginsbootstrap.sh — creates directories, loads config
PreToolUse (Bash)Before any Bash commandpre-tool-security-gate.sh — blocks dangerous commands
PostToolUse (Write)After file writesFeedback capture, drift detection, roles sync
PostToolUse (Bash)After Bash commandsRoadmap suggestion after commits
TaskCompletedAfter agent tasksQuality gate check
StopSession endssession-end.sh — cleanup

Key Properties​

  • Non-blocking: All hooks exit 0 by default. A hook failure never blocks your work.
  • Read-only checks: PostToolUse hooks only read files and print suggestions.
  • Security gate: The PreToolUse hook can block dangerous Bash commands before execution.
  • No secrets: Hooks never read .env files or credentials.
  • Auditable: Every hook command is defined in hooks/hooks.json and points to a visible script.

Permission Model​

Skill-Level Permissions​

Each skill declares exactly which tools it can use in its allowed-tools frontmatter. Skills cannot access tools outside their allowlist.

Examples of narrowly-scoped permissions:

  • Write($JAAN_OUTPUTS_DIR/**) — can only write to outputs directory
  • Bash(npm test:*) — can only run test commands, not arbitrary npm
  • Edit(src/**) — can only edit source files, not config or secrets

What's NOT allowed:

  • No skill has Read(.env*) or access to secret files
  • No skill has bare Bash (unrestricted shell access)
  • No skill has bare Edit (unrestricted file editing)
  • No skill can run npm install of arbitrary packages without explicit scoping

Human Approval Gates​

Every write-heavy skill follows the HARD STOP pattern:

  1. Analyze and plan (read-only)
  2. Show complete preview of what will change
  3. Wait for explicit user approval
  4. Only then write files

You always see what will happen before it happens.

Claude Code Layer​

On top of skill permissions, Claude Code's own permission system applies. You can further restrict operations in .claude/settings.json. See Permissions for details.


Data Privacy​

What Stays Local​

  • All processing runs locally on your machine via Claude Code
  • Generated outputs, learned lessons, and config are local files
  • No data is collected, transmitted, or stored externally
  • No analytics, telemetry, or usage tracking

External Interactions​

When a skill does interact externally (only with your explicit approval):

SkillExternal ServiceWhat's SentSanitization
jaan-issue-reportGitHub IssuesBug report textPaths, credentials, personal info redacted
pm-research-aboutPublic webSearch queriesNo project data sent
devops-deploy-activateGitHub, Vercel, etc.Deployment configSecrets entered by user, never logged

Privacy Sanitization​

Before any external submission, jaan-to sanitizes:

  • Absolute paths (/Users/you/... becomes {USER_HOME}/...)
  • Credentials (ghp_*, sk-*, Bearer *, API keys)
  • Database connection strings (postgresql://, mongodb://, etc.)
  • Personal information (emails, IPs embedded in paths)

What You Can Customize​

WhatWhereEffect
Output pathsjaan-to/config/settings.yamlRedirect where outputs are written
Languagesettings.yaml → languageUI language for skill output
Safety boundariesjaan-to/context/boundaries.mdCustom rules skills must follow
Feature togglessettings.yaml → feature flagsEnable/disable specific behaviors
Templatesjaan-to/templates/Customize output formats
Claude Code permissions.claude/settings.jsonAllow/deny rules at the CLI level

All customization uses local files. No account, registration, or cloud config needed.


Path Security​

jaan-to validates all configurable paths to prevent directory traversal attacks:

  • No .. segments: Paths containing .. are rejected
  • No absolute paths: Paths starting with / are rejected
  • Canonical validation: After resolution, paths are verified to stay within the project directory using realpath
  • Template imports: {{import:path}} directives are validated before reading any file

A malicious settings.yaml with paths_outputs: "../../.ssh" would be rejected with a clear error.


Temp File Safety​

Plugin scripts that use temporary files:

  • Create them with mktemp (unpredictable filenames, atomic creation)
  • Clean them up via trap cleanup EXIT
  • Never store sensitive data in temp files

Uninstalling​

To completely remove jaan-to from a project:

  1. Remove the plugin from Claude Code settings (.claude/settings.json)
  2. Delete the jaan-to/ directory from your project
  3. Done

There are no system-level changes to undo, no background processes, no global config files, and no remote accounts to deactivate.