Rule set 2026.07.1
Rule Catalog
Every TrueTag finding carries the identifier and version of the rule that produced it. This page lists the 84 statically defined rules and the dynamic rule families in the current release, so a verdict can always be traced to the exact checks that ran.
A scan reports only what these rules can observe within the disclosed scope. “No findings” means no configured rule matched — it is not a certification that an application is secure, accessible, or legally compliant, and it does not replace penetration testing, professional accessibility testing, or legal advice.
Published corpus metrics
Precision and recall from the adjudicated CI corpus (36 cases, generated 2026-07-26). Launch-blocking families must stay at ≥ 98% precision on this corpus. Regenerated by pnpm evaluate:rules.
| Family | Cases | Precision | Recall | Promotion |
|---|---|---|---|---|
| Secrets | 25 | 100.0% | 100.0% | allowed |
| Dependencies | 20 | 100.0% | 100.0% | allowed |
| Configuration | 20 | 100.0% | 100.0% | allowed |
Committed secrets
stableDeterministic credential patterns with entropy and placeholder guards. Matched values are redacted before storage and are never sent to a model provider.
| Rule ID | Severity | What it detects |
|---|---|---|
| repo_secrets.aws_access_key | critical | Committed AWS access key ID |
| repo_secrets.aws_secret_key | critical | Committed AWS secret access key |
| repo_secrets.gcp_service_account | critical | Committed Google Cloud service-account key |
| repo_secrets.gcp_api_key | high | Committed Google API key |
| repo_secrets.stripe_live_secret | critical | Committed Stripe live secret key |
| repo_secrets.stripe_test_secret | medium | Committed Stripe test secret key |
| repo_secrets.stripe_webhook_secret | high | Committed Stripe webhook signing secret |
| repo_secrets.github_token | critical | Committed GitHub token |
| repo_secrets.github_pat_fine | critical | Committed GitHub fine-grained PAT |
| repo_secrets.openai_key | high | Committed OpenAI API key |
| repo_secrets.anthropic_key | high | Committed Anthropic API key |
| repo_secrets.slack_token | high | Committed Slack token |
| repo_secrets.sendgrid_key | high | Committed SendGrid API key |
| repo_secrets.twilio_key | high | Committed Twilio API key |
| repo_secrets.supabase_service_role | critical | Committed Supabase service-role JWT |
| repo_secrets.private_key_block | critical | Committed Private key material |
| repo_secrets.database_url | critical | Committed Database connection string with password |
| repo_secrets.jwt_secret_assignment | high | Committed Hard-coded JWT/session secret |
| repo_secrets.generic_api_key | high | Committed API key or token |
| repo_secrets.password_assignment | high | Committed Hard-coded password |
| repo_secrets.smtp_credentials | high | Committed SMTP credentials |
| repo_secrets.vercel_token | high | Committed Vercel token |
| repo_secrets.firebase_fcm_key | high | Committed Firebase Cloud Messaging server key |
| repo_secrets.bearer_token | high | Committed Hard-coded bearer token |
| repo_secrets.committed_env_file | high | Environment file committed to the repository |
Dependencies and SBOM
stablePackage inventory across npm and pip manifests, advisory matching against the GitHub Advisory Database and OSV, and CycloneDX SBOM generation.
| Rule ID | Severity | What it detects |
|---|---|---|
| repo_dependencies.vulnerable_package | varies | Dependency version matched a published security advisory |
| repo_dependencies.unpinned_dependency | low | Dependency accepts any version |
| repo_dependencies.missing_lockfile | medium | No lockfile committed |
Authentication and authorization
betaHeuristic checks for unauthenticated admin or mutating routes, bypass flags, and weak credential handling.
| Rule ID | Severity | What it detects |
|---|---|---|
| repo_auth.admin_route_no_auth | critical | Admin route appears to lack an authentication check |
| repo_auth.mutating_route_no_auth | high | State-changing route without a recognized authentication check |
| repo_auth.hardcoded_email_check | medium | Authorization decided by a hard-coded email comparison |
| repo_auth.auth_bypass_flag | high | Authentication bypass flag present in code |
| repo_auth.token_in_localstorage | medium | Auth token stored in localStorage |
| repo_auth.weak_password_hashing | high | Passwords hashed with a fast, unsalted algorithm |
Configuration and backend services
stableDeployment configuration, CORS, and Firebase/Supabase backend policy checks.
| Rule ID | Severity | What it detects |
|---|---|---|
| repo_config.debug_enabled | high | Debug mode enabled in configuration |
| repo_config.cors_wildcard | high | CORS allows any origin (severity rises when credentials are also allowed) |
| repo_config.localhost_in_config | low | Localhost URL in production-oriented configuration |
| repo_config.committed_source_maps | low | Production source maps committed to the repository |
| repo_config.firebase_open_rules | critical | Firebase rules allow public read or write access |
| repo_config.supabase_service_role_public | critical | Supabase service-role key exposed with a public env prefix |
| repo_config.supabase_rls_disabled | high | Row-level security disabled on a table |
| repo_config.supabase_permissive_policy | high | Supabase policy uses USING (true) |
Input and output handling
betaInjection and unsafe-rendering checks across request handling and templating.
| Rule ID | Severity | What it detects |
|---|---|---|
| repo_input.dangerous_inner_html | high | Unsanitized HTML rendered with dangerouslySetInnerHTML |
| repo_input.inner_html_assignment | medium | Dynamic value assigned to innerHTML |
| repo_input.sql_injection | high | SQL query built by string concatenation |
| repo_input.command_injection | high | Shell command built from interpolated input |
| repo_input.path_traversal | high | File path built from request input without containment check |
| repo_input.open_redirect | medium | Redirect target taken directly from request input |
| repo_input.unrestricted_upload | medium | File upload without visible size or type restrictions |
Payments
betaStripe integration checks for webhook verification and trusted amount handling.
| Rule ID | Severity | What it detects |
|---|---|---|
| repo_payments.webhook_no_signature | critical | Stripe webhook handler does not verify the signature |
| repo_payments.client_amount | high | Payment amount taken from the client request |
| repo_payments.secret_key_client | critical | Stripe secret key exposed to the frontend |
AI system security
betaPrompt-injection surfaces, unsafe model-output handling, agency limits, and AI system-graph checks aligned with the OWASP LLM Top 10.
| Rule ID | Severity | What it detects |
|---|---|---|
| ai_security.prompt_injection_surface | high | User input concatenated directly into a model prompt |
| ai_security.unsafe_output_handling | high | Model output may be rendered as HTML or executed |
| ai_security.excessive_agency | high | AI agent can take high-impact actions without a human check |
| ai_security.secret_in_prompt | medium | A secret appears to be placed inside a model prompt |
| ai_graph.retrieval_tenant_scope_unverified | high | Retrieval tenant isolation is not evident |
| ai_graph.high_impact_tool_without_approval | high | High-impact AI tool lacks a recognized approval gate |
| ai_graph.unvalidated_output_sink | high | Model output reaches a privileged sink without recognized validation |
| ai_graph.provider_disclosure_mismatch | medium | Detected AI provider is missing from the disclosed provider list |
artifact.tt-art-* — Artifact Guard findings re-emitted for instruction and automation files found in the repository
Artifact Guard (pre-install)
stableDeterministic checks applied to pasted or acquired AI skills, agent instructions, manifests, and tool definitions before installation.
| Rule ID | Severity | What it detects |
|---|---|---|
| TT-ART-001 | critical | Instruction hierarchy override |
| TT-ART-002 | critical | Secret or environment-variable harvesting |
| TT-ART-003 | critical | Downloaded content executed directly |
| TT-ART-004 | high | Unrestricted command execution |
| TT-ART-005 | high | Install-time execution hook |
| TT-ART-006 | high | Instruction to disclose protected context |
| TT-ART-007 | high | Hidden instruction in HTML comment |
| TT-ART-008 | high | Visually concealed content |
| TT-ART-009 | medium | Encoded or obfuscated payload |
| TT-ART-010 | critical | Destructive filesystem command |
| TT-ART-011 | high | Invisible Unicode control characters |
Live-site transport, headers, cookies, and legal pages
stableDNS-pinned, GET/HEAD-only probes of the running site: TLS, security headers, cookie flags, mixed content, exposed paths, and required legal pages.
| Rule ID | Severity | What it detects |
|---|---|---|
| live_site.no_https | high | Site served over plain HTTP |
| live_site.tls_invalid | high | TLS certificate invalid |
| live_site.tls_expiring | medium | TLS certificate close to expiry |
| live_site.header_frame | low | No clickjacking protection (frame-ancestors or X-Frame-Options) |
| live_site.cookie_flags | medium | Cookie set without recommended security flags |
| live_site.mixed_content | medium | HTTPS page loads active content over HTTP |
| live_site.exposed_sensitive_path | varies | A sensitive path responds publicly |
| live_site.header_csp | medium | Missing Content-Security-Policy header |
| live_site.header_hsts | medium | Missing Strict-Transport-Security header |
| live_site.header_xcto | low | Missing X-Content-Type-Options header |
| live_site.header_referrer | low | Missing Referrer-Policy header |
| live_site.missing_privacy_policy | medium | No Privacy Policy link found on the homepage |
| live_site.missing_terms | low | No Terms link found on the homepage |
Accessibility (WCAG 2.2 AA automation)
axe-core automated checks executed against the rendered page. Automated coverage is partial by nature; manual review remains necessary.
accessibility.<axe-rule-id> — One finding per violated axe-core rule, carrying the upstream rule identifier and WCAG mapping
External engines
Pinned external scanners (Gitleaks, OSV-Scanner, Trivy, Semgrep CE, YARA, and ClamAV) whose results are normalized into the same evidence model. Engine versions are recorded on every scan.
TT-EXT-<ENGINE>-<rule> — One finding per upstream engine rule hit, prefixed by the engine name