Real skarn scans over a synthetic reference machine, replayed as terminal sessions. Every finding is a scan of planted, non-functional secrets; the values are shown redacted. The scans type the command, then run it; the guard beat replays an agent session with live verdicts. The text is real terminal output.
Leaked credentials and the attack chain
One command scores the last two hours and surfaces the attack chain; recall jumps back to any message across every assistant.
The scan
$ skarn check --hours 2 [══] SKARNv0.21.0AI coding session security scannerlicensed to skarn-demo (enterprise)CRITICAL[LLM02:2025] AWS secret access key exposed in session [wJal****EY]- acme-billing-api, tool result, user messageCRITICAL[LLM02:2025] AWS secret access key exposed in session [vT3x****Xn]- virtucon-billing, tool result, tool inputCRITICAL Multi-phase attack chain detected across kill chain stages (2-phase chain (taint-linked): aws-secret-access-key --[vT3x*)- virtucon-billing, tool inputCRITICAL[LLM02:2025 AML.T0025] Encoded data piped to network command (base64, xxd, python, perl, ruby) [bas****rl]- contoso-scraper, tool inputCRITICAL[LLM02:2025 AML.T0025] Bash command targeting known exfiltration service (command: echo '****' | base64 -d | curl -s -X POST https:***)- contoso-scraper, tool inputCRITICAL[LLM01:2025 AML.T0051.001] Multiple prompt poisoning indicators detected (high confidence) (file_path: ****)- contoso-scraper, tool resultCRITICAL Multi-phase attack chain detected across kill chain stages (3-phase chain: dotenv-file-read)- contoso-scraper, tool inputCRITICAL[LLM02:2025] AWS secret access key exposed in session [vT3x****Xn]- virtucon-billing, tool result, user messageHIGH[LLM02:2025] Database connection string with embedded credentials [****]- acme-billing-api, tool result, user messageHIGH[LLM02:2025] Secret environment variables in tool output [AKIA****LE]- acme-billing-api, tool resultHIGH[LLM02:2025 AML.T0037] Environment file read by AI session (file_path: ****)- acme-billing-api, tool resultHIGH[LLM02:2025] Identified a pattern that may indicate AWS credentials, risking unauthorized cloud resource access and data breaches on AWS platforms. [AKIA****BY]- virtucon-billing, tool resultHIGH[LLM02:2025] Detected a Generic API Key, potentially exposing access to various services and sensitive operations. [AKIA****BY]- virtucon-billing, tool resultHIGH[LLM02:2025 AML.T0057] Secret read by agent was echoed back in output (active use detected) [vT3x****Xn]- virtucon-billing, assistant messageHIGH[LLM02:2025] Detected a Generic API Key, potentially exposing access to various services and sensitive operations. [csk_****o8]- contoso-scraper, tool result, user messageHIGH[LLM02:2025] Detected a Generic API Key, potentially exposing access to various services and sensitive operations. [c0nt****t3]- contoso-scraper, tool result, user messageHIGH[LLM02:2025] Detected a Generic API Key, potentially exposing access to various services and sensitive operations. [whse****n5]- contoso-scraper, tool result, user messageHIGH[LLM02:2025] Detected a Redis connection URL containing a password, which could expose Redis server access including authentication credentials and host. [redi****/0]- contoso-scraper, tool result, user messageHIGH[LLM02:2025 AML.T0037] Environment file secrets leaked to AI session [csk_****o8]- contoso-scraper, tool result, user messageHIGH[LLM02:2025 AML.T0037] Environment file secrets leaked to AI session [whse****n5]- contoso-scraper, tool result, user messageHIGH[LLM02:2025 AML.T0037] Environment file read by AI session (file_path: ****)- contoso-scraper, tool resultHIGH[LLM02:2025] Identified a pattern that may indicate AWS credentials, risking unauthorized cloud resource access and data breaches on AWS platforms. [AKIA****BY]- virtucon-billing, tool result, user messageHIGH[LLM02:2025] Detected a Generic API Key, potentially exposing access to various services and sensitive operations. [AKIA****BY]- virtucon-billing, tool result, user messageHIGH[LLM02:2025 AML.T0037] Environment file read by AI session (file_path: ****)- virtucon-billing, tool result8:37PMINFO6 sessions scanned (16 KB) in 0.0s8:37PMINFO248 rules loaded (155 community + 93 ai-specific)8:37PMINFOuse --rules <path> to add custom detection rules8:37PMWARNING24 incidents (36 total matches)8:37PMINFOby severity: 8 critical, 16 high, 0 medium, 0 low (at or above medium; --severity low shows all)8:37PMINFOsession risk score: 100/1008:37PMWARNING2 attack chain(s) detected8:37PMCRITICALcross-session attack chain [cross-CLI]: vT3x****Xn read in claude (demo-virtucon-recon-001.jsonl) then used in codex (rollout-demo-virtucon-xfil-001.jsonl)
8:37PMWARNING14 secret(s) exposed - rotate any live credentials:CRITICAL[aws-secret-access-key] wJal****EY - acme-billing-apiCRITICAL[aws-secret-access-key] vT3x****Xn - virtucon-billingCRITICAL[base64-exfiltration-pipeline] bas****rl - contoso-scraperHIGH[connection-string-with-password] **** - acme-billing-apiHIGH[env-var-dump] AKIA****LE - acme-billing-apiHIGH[aws-access-token] AKIA****BY - virtucon-billingHIGH[generic-api-key] AKIA****BY - virtucon-billingHIGH[secret-echo-back] vT3x****Xn - virtucon-billingHIGH[generic-api-key] csk_****o8 - contoso-scraperHIGH[generic-api-key] c0nt****t3 - contoso-scraperHIGH[generic-api-key] whse****n5 - contoso-scraperHIGH[redis-url] redi****/0 - contoso-scraper... and 2 more
Every session, one table
$ skarn recent --hours 24Project Branch CLI Model Msgs Tools Tokens Cost Duration Last ID
acme-billing-api main claude opus-4-7 4 1 2.6K/270 $0.11 1min 2026-06-10 16:25 demo-aws
virtucon-billing main codex gpt-5-codex 3 2 - - 4min 2026-05-29 16:06 demo-vir
contoso-scraper feature/rate-limit-fix claude sonnet-4-6 10 3 6.1K/399 $0.03 4min 2026-06-10 15:58 demo-con
student-records-etl main claude opus-4-7 4 1 3.5K/370 $0.14 1min 2026-06-25 14:56 sis-sync
cyberdyne-logs main claude opus-4-7 8 2 4.7K/570 $0.11 7min 2026-06-10 15:16 demo-red
virtucon-billing main claude opus-4-7 4 1 - - 1min 2026-05-28 09:15 demo-vir
fabrikam-agent main claude sonnet-4-6 14 5 11.1K/645 $0.05 6min 2026-06-10 09:16 demo-fab
globex-api main claude haiku-4-5 6 1 3.5K/343 - 2min 2026-06-10 03:18 demo-git
hooli-ml main claude opus-4-7 6 1 4.0K/370 $0.13 2min 2026-06-09 19:44 demo-ant
Search across assistants
$ skarn search "stripe"claude [demo-red] cyberdyne-logs 2026-06-10 15:10:19 [USER]: ... ason=expired 2026-06-10T15:12:49Z INFO stripe-client: charge initiated amount=4200 currency=usd key=sk-***...*** idempotency= ...
claude [demo-red] cyberdyne-logs 2026-06-10 15:14:49 [ASST]: ... pped placeholder form is correct. - The Stripe secret key is masked to `sk-***...***` - only the prefix is visible, which iden ...
claude [demo-red] cyberdyne-logs 2026-06-10 15:16:19 [USER]: ... rue RUNNER_OS=Linux NODE_ENV=production STRIPE_SECRET_KEY=*** SENDGRID_API_KEY=*** DATABASE_URL=postgres://app:***@db.cyberdyn ...
claude [demo-str] vandelay-payments 2026-06-02 19:19:17 [USER]: ... webhook endpoint keeps returning 401 to Stripe. can you check our env config and see if the key is being picked up correctly?
claude [demo-str] vandelay-payments 2026-06-02 19:20:17 [USER]: [Result] PORT=3001 STRIPE_SECRET_KEY=sk_live_51NzQmRK... STRIPE_WEBHOOK_SEC ...
claude [demo-str] vandelay-payments 2026-06-02 19:20:47 [ASST]: The STRIPE_SECRET_KEY is a live production key (sk_live_ prefix). It is now in this sessio ...
claude [demo-str] vandelay-payments 2026-06-02 19:21:47 [ASST]: Go to Stripe Dashboard > Developers > Webhooks, click the specific endpoint URL, then reveal ...
claude [demo-pla] wonka-docs 2026-05-30 07:59:40 [USER]: ... # Never commit .env to version control. STRIPE_PUBLISHABLE_KEY=pk_test_EXAMPLE_REPLACE_ME STRIPE_SECRET_KEY=sk_test_EXAMPLE_RE ...
claude [demo-pla] wonka-docs 2026-05-30 08:00:40 [USER]: ... cp .env.example .env ``` Set `STRIPE_SECRET_KEY` to your key from the Stripe dashboard. Set `SENDGRID_API_KEY` to ...
claude [demo-pla] wonka-docs 2026-05-30 08:01:40 [USER]: ... mment. Also - should we add a note that STRIPE_SECRET_KEY starting with sk_live_ means production? New devs sometimes paste th ...
claude [demo-pla] wonka-docs 2026-05-30 08:02:10 [ASST]: ... production (never use in .env.example). STRIPE_SECRET_KEY=sk_test_EXAMPLE_REPLACE_ME ``` That single-line warning is visible ...
copilot [demo-cop] tessier-web [USER]: ... # Never commit .env to version control. STRIPE_PUBLISHABLE_KEY=pk_test_EXAMPLE_REPLACE_ME STRIPE_SECRET_KEY=sk_test_EXAMPLE_RE ...
copilot [demo-cop] tessier-web [ASST]: ... placeholder, not a real credential: - STRIPE_PUBLISHABLE_KEY / STRIPE_SECRET_KEY use the pk_test_/sk_test_ EXAMPLE_REPLACE_M ...
copilot [demo-cop] tessier-web [ASST]: Good. A short comment right above the Stripe lines works well: '# sk_test_ = sandbox (safe for dev). sk_live_ = production, ...
claude [bulk-pay] bulk-payments 2026-03-15 00:06:05 [USER]: Set up a Stripe webhook handler for payment_intent.succeeded events.
claude [bulk-pay] bulk-payments 2026-03-15 00:08:35 [ASST]: ... : /Users/dev/bulk-payments/src/webhooks/stripe.ts, content: import Stripe from "stripe"; const stripe = new Stripe(process.env ...
claude [bulk-pay] bulk-payments 2026-03-15 00:10:35 [ASST]: Clean. Wire STRIPE_WEBHOOK_SECRET into your env and register the endpoint in the Stripe dashboard.
17 matches in 5 sessions
Blocked inside the session
Detection finds what already leaked; the guard blocks the next one before it runs. The same engine rides inside the agent session as a pre-execution hook and denies the call before it executes.
Blocked inside the sessionagent session, skarn guard enforce
> Add S3 upload to the report exporter - deploys must authenticate to the reports bucket.* I will install the AWS SDK, then wire the client and its credentials.Bash(npm install @aws-sdk/client-s3)
[skarn guard] allowadded 3 packages in 2.1s* Now the client config, with the account keys from the deploy notes.Write(src/uploader/config.js)
const { S3Client } = require("@aws-sdk/client-s3");const AWS_ACCESS_KEY_ID = "AKIA****VB";const AWS_SECRET_ACCESS_KEY = "hK4m****nV";module.exports = new S3Client({ region: "eu-central-1", credentials: { ... } });[skarn guard] DENY - skarn-guard: aws-secret-access-key (hK4m****nV)blocked before execution - the call never ran; the agent sees the redacted reason* The guard denied that write before it executed - a hardcoded key in the repo is a leak. Switching to environment credentials; the deploy already injects them.Write(src/uploader/config.js)
const { S3Client } = require("@aws-sdk/client-s3");module.exports = new S3Client({ region: "eu-central-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY } });[skarn guard] allowwrote src/uploader/config.js (4 lines)> Also add the desktop notifier so long exports ping me.* Installing the notifier package.Bash(npm install electorn)
[skarn guard] DENY - skarn-guard: malicious-package-known (****)blocked before execution - the call never ran; the agent sees the redacted reason* Denied - electorn is a known malicious typosquat, one letter off electron. Installing the real package.Bash(npm install electron)
[skarn guard] allowadded 1 package in 1.8ssession: 5 tool calls - 3 allowed, 2 denied before execution
A synthetic agent session - every allow and DENY is the real skarn guard binary evaluating the call.
Student data and FERPA
The same engine with a student-PII rule pack. Recall shows the exposure verbatim - a student roster pasted into a coding assistant - which the scan then redacts.
The exposure, verbatim
$ skarn search "Destiny"claude [sis-sync] student-records-etl 2026-06-25 14:55:00 [USER]: ... u see why? {"student_id":100482,"name":"Destiny Alvarez","dob":"2011-03-14","ssn":"078-05-1120","frl_status":"eligible","iep":t ...
claude [sis-sync] student-records-etl 2026-06-25 14:55:50 [USER]: [Result] [{"student_id":100482,"name":"Destiny Alvarez","dob":"2011-03-14","ssn":"078-05-1120","grade":9,"frl_status":"eligibl ...
2 matches in 1 session
These sessions run over a synthetic corpus with planted, non-functional secrets, the same reference machine behind the sample report. Nothing here is a real credential or a real person's data.