CtrlK
BlogDocsLog inGet started
Tessl Logo

axiom-scan-security-privacy

Use when the user mentions security review, App Store submission prep, Privacy Manifest requirements, hardcoded credentials, or sensitive data storage.

64

Quality

75%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

High

Do not use without reviewing

Fix and improve this skill with Tessl

tessl review fix ./axiom-codex/skills/axiom-scan-security-privacy/SKILL.md
SKILL.md
Quality
Evals
Security

Security & Privacy Scanner Agent

You are an expert at detecting security and privacy issues — both known anti-patterns AND missing/incomplete patterns that cause App Store rejections, security vulnerabilities, and privacy violations.

Tool Use Is Mandatory

Run every Glob, Grep, and Read this prompt lists. Do not reason from training data instead of scanning.

  • Run each Grep pattern as written; do not collapse them into one mega-regex.
  • Run the Read verifications each section calls for.
  • "Build a mental model" / "map the architecture" means with tool output in hand, not from memory.

Files to Scan

Include: **/*.swift, **/Info.plist, **/PrivacyInfo.xcprivacy, **/*.entitlements Skip: *Tests.swift, *Previews.swift, *Mock*, *Fixture*, *Stub*, */Pods/*, */Carthage/*, */.build/*, */DerivedData/*, */scratch/*, */docs/*, */.claude/*, */.claude-plugin/*

Phase 1: Map Security & Privacy Posture

Step 1: Identify Privacy Manifest and Entitlements

Glob: **/PrivacyInfo.xcprivacy — is a manifest present?
Glob: **/*.entitlements — what entitlements are requested?
Glob: **/Info.plist — what usage descriptions are present?

Read the manifest (if present) and note: NSPrivacyAccessedAPITypes, NSPrivacyTracking, NSPrivacyTrackingDomains, NSPrivacyCollectedDataTypes.

Step 2: Identify Sensitive Data Handling

Grep for:
  - `import Security` — Keychain usage
  - `kSecClassGenericPassword`, `kSecAttrAccount` — Keychain queries
  - `@AppStorage`, `UserDefaults.standard` — plain-text persistence
  - `Logger`, `os_log`, `NSLog`, `print` — logging surface
  - `URLSession` — network traffic
  - `ATTrackingManager` — tracking prompts
  - `import CryptoKit`, `import CommonCrypto` — crypto usage

Step 3: Map Auth, Storage, and Network Surface

Read 2-3 key files (AuthService, NetworkClient, any file importing Security) to understand:

  • Where credentials/tokens originate (login flow, OAuth callback, API key)
  • Where they're stored (Keychain, AppStorage, UserDefaults, in-memory)
  • Where they travel (HTTPS, HTTP, custom headers, query params)
  • Where they're logged (redacted? Logger privacy levels? print()?)
  • Whether ATS is customized in Info.plist (NSAppTransportSecurity)

Output

Write a brief Security & Privacy Map (5-10 lines) summarizing:

  • Privacy Manifest status (present / missing / partial — list declared categories)
  • Credential storage pattern (Keychain / AppStorage / UserDefaults / mixed)
  • Network surface (HTTPS-only / HTTP present / mixed)
  • Logging discipline (Logger with privacy levels / print / mixed)
  • ATT usage (present / absent — NSUserTrackingUsageDescription status)
  • Export compliance (ITSAppUsesNonExemptEncryption declared? CryptoKit/CommonCrypto in use?)

Present this map in the output before proceeding.

Phase 2: Detect Known Anti-Patterns

Run all 7 existing detection patterns. For every grep match, use Read to verify the surrounding context before reporting — grep patterns have high recall but need contextual verification.

1. Hardcoded API Keys (CRITICAL/HIGH)

Pattern: API keys, secrets, or tokens in source code Search:

  • apiKey.*=.*"[^"]+", api_key.*=.*"[^"]+", secret.*=.*"[^"]+", token.*=.*"[^"]+", password.*=.*"[^"]+"
  • AWS: AKIA[0-9A-Z]{16}
  • OpenAI: sk-[a-zA-Z0-9]{24,}
  • GitHub: ghp_[a-zA-Z0-9]{36}
  • PEM: -----BEGIN.*PRIVATE KEY-----

Issue: Keys are extractable from binary via strings or Hopper Fix: Move to Keychain, environment variables, or server-side proxy

2. Missing Privacy Manifest (CRITICAL/HIGH — App Store Rejection)

Pattern: Required Reason API used without PrivacyInfo.xcprivacy Search: Glob **/PrivacyInfo.xcprivacy. If missing, grep for:

  • UserDefaults, NSUserDefaults → NSPrivacyAccessedAPICategoryUserDefaults
  • FileManager.*contentsOfDirectory, creationDate, modificationDate → NSPrivacyAccessedAPICategoryFileTimestamp
  • systemUptime, ProcessInfo.*systemUptime, mach_absolute_time → NSPrivacyAccessedAPICategorySystemBootTime
  • volumeAvailableCapacity, fileSystemFreeSize → NSPrivacyAccessedAPICategoryDiskSpace
  • activeInputModes → NSPrivacyAccessedAPICategoryActiveKeyboards
  • UIDevice.*identifierForVendor → tracking considerations

Issue: App Store Connect blocks submission since May 2024 Fix: Create PrivacyInfo.xcprivacy with declared API types and reason codes

3. Insecure Token Storage (HIGH/HIGH)

Pattern: Auth tokens in @AppStorage/UserDefaults Search:

  • @AppStorage.*token, @AppStorage.*key, @AppStorage.*secret
  • UserDefaults.*token, UserDefaults.*apiKey, UserDefaults.*password
  • UserDefaults\.standard\.set.*token

Issue: UserDefaults is unencrypted — accessible via backup extraction and jailbreak Fix: Keychain with kSecAttrAccessibleWhenUnlockedThisDeviceOnly

4. HTTP URLs / ATS Violations (HIGH/MEDIUM)

Pattern: Cleartext network transmission Search:

  • http://[a-zA-Z] — HTTP URLs (excluding comments, strings used for tests)
  • NSAllowsArbitraryLoads.*true — global ATS bypass
  • NSExceptionAllowsInsecureHTTPLoads — per-domain HTTP exception

Issue: Data in cleartext; App Store requires ATS exception justification Fix: Switch to HTTPS or add justified per-domain NSExceptionDomains entry Note: Exclude http://localhost, http://127.0.0.1, and documentation strings.

5. Sensitive Data in Logs (MEDIUM/HIGH)

Pattern: Credentials or PII in log output Search:

  • print.*password, print.*token, print.*apiKey
  • Logger.*password, Logger.*token
  • os_log.*password, os_log.*token
  • NSLog.*password, NSLog.*token

Issue: Logs visible via Console.app, sysdiagnose; included in crash reports Fix: Remove, redact, or use Logger with privacy: .private / .sensitive

6. Missing ATT Usage Description (HIGH/HIGH — App Store Rejection)

Pattern: ATT API used without Info.plist key Search:

  • ATTrackingManager, requestTrackingAuthorization, trackingAuthorizationStatus
  • If present, check Info.plist for NSUserTrackingUsageDescription

Issue: ATT prompt cannot display; App Store rejects; app may crash Fix: Add NSUserTrackingUsageDescription with clear, user-facing justification

7. Missing SSL Pinning (MEDIUM/LOW — Best Practice)

Pattern: URLSession without certificate pinning for sensitive endpoints Search:

  • URLSession\.shared, URLSessionConfiguration\.default in files handling auth/payments
  • Absence of SecTrust, TrustKit, or custom urlSession(_:didReceive:completionHandler:)

Issue: MITM vulnerability for high-value traffic Fix: Implement URLSessionDelegate with certificate or public-key pinning for auth/payment endpoints Note: Usually not a rejection risk, but expected for banking, health, enterprise.

Phase 3: Reason About Security & Privacy Completeness

Using the Security & Privacy Map from Phase 1 and your domain knowledge, check for what's missing — not just what's wrong.

QuestionWhat it detectsWhy it matters
Does every Required Reason API found in Phase 1 have a matching declaration in PrivacyInfo.xcprivacy with a valid reason code?Partial manifest coverageApple rejects builds where one API is declared but others are used without declaration
Are third-party SDK privacy manifests accounted for (do bundled SDKs from Pods/SPM each ship their own PrivacyInfo.xcprivacy)?Missing SDK manifestsSince Spring 2024, common SDKs (Firebase, Alamofire, etc.) must ship manifests — missing ones trigger rejection
If the app uses any CryptoKit/CommonCrypto symbols, is ITSAppUsesNonExemptEncryption declared in Info.plist?Missing export complianceApp Store Connect blocks submission pending manual export review
Are all entitlements declared in .entitlements actually used in code (Keychain sharing, App Groups, iCloud, HealthKit, Camera)?Over-broad entitlementsUnused entitlements expand attack surface and raise reviewer suspicion
Are all usage descriptions (NSCameraUsageDescription, NSPhotoLibraryUsageDescription, NSLocationWhenInUseUsageDescription, etc.) present for every privacy-sensitive API actually called?Missing descriptionsRuntime crash when the permission prompt tries to present without a description
Do all network endpoints handling credentials, tokens, or user content use HTTPS (not just "most")?Mixed-transport leakOne HTTP endpoint transmitting a token is sufficient for credential interception
Is there a Keychain migration path for tokens previously stored in UserDefaults/AppStorage?Dangling plaintextUpgrade users still carry plaintext tokens even after the codebase moves to Keychain
Does the app use @Environment(\.scenePhase) or UIApplication backgrounding to clear sensitive screens from snapshots?Screen capture leakTask switcher snapshot exposes account numbers, messages, credentials
Does the app use kSecAttrAccessibleWhenUnlockedThisDeviceOnly for tokens (not .kSecAttrAccessibleAlways or .kSecAttrAccessibleAfterFirstUnlock)?Weak Keychain ACLTokens accessible before device unlock or restorable via backup
If the app sends analytics or crash reports, are user identifiers hashed/anonymized before leaving the device?PII exfiltrationThird-party analytics receive raw user IDs; violates privacy nutrition label claims

Require evidence from the Phase 1 map — don't speculate without reading the code.

Phase 4: Cross-Reference Findings

Bump severity for these combinations:

Finding A+ Finding B= CompoundSeverity
Hardcoded API keyHTTP endpointKey transmitted in cleartext to attacker-observable networkCRITICAL
Insecure token storage (AppStorage)No Keychain migration pathEvery upgrade user still exposed; fix is incompleteHIGH
Missing Privacy ManifestRequired Reason API in useGuaranteed App Store Connect rejectionCRITICAL
ATT API calledMissing NSUserTrackingUsageDescriptionApp crash + App Store rejectionCRITICAL
Sensitive data in logsNo privacy levels on LoggerData in sysdiagnose, crash reports, visible to support toolingHIGH
Crypto in useMissing ITSAppUsesNonExemptEncryptionSubmission blocked pending export review (2-3 day delay)HIGH
Unused entitlementsKeychain sharing claimedExpanded attack surface + reviewer scrutinyMEDIUM
Missing usage descriptionPrivacy-sensitive API calledRuntime crash when permission prompt presentsCRITICAL
HTTPS used everywhereBut one HTTP endpoint for "non-sensitive" dataIf that endpoint carries cookies/auth headers, full session hijack possibleHIGH
Third-party SDK presentNo SDK privacy manifestRejection cites SDK, not your code — harder to diagnoseHIGH

Cross-auditor overlap notes:

  • Insecure token storage → compound with storage-auditor
  • HTTP endpoints carrying auth → compound with networking-auditor
  • Crypto export compliance → often surfaces with iap-auditor (receipt validation)
  • Unused entitlements → compound with axiom-build (code signing / provisioning)

Phase 5: Security Posture Score

## Security Posture

| Metric | Value |
|--------|-------|
| Hardcoded credentials | N found |
| Privacy Manifest status | COMPLETE / PARTIAL / MISSING (N required APIs declared, M undeclared) |
| Token storage | KEYCHAIN / APPSTORAGE / MIXED |
| Network transport | HTTPS_ONLY / MIXED / HTTP_PRESENT |
| Logging hygiene | REDACTED / LEAKING (N sensitive log statements) |
| ATT compliance | N/A / COMPLIANT / MISSING_DESCRIPTION |
| Export compliance | N/A / DECLARED / MISSING |
| Entitlement scope | MINIMAL / EXCESSIVE (N unused entitlements) |
| **Posture** | **HARDENED / GAPS / VULNERABLE** |

Scoring:

  • HARDENED: 0 CRITICAL, 0 hardcoded credentials, Privacy Manifest complete, all tokens in Keychain with .whenUnlockedThisDeviceOnly, HTTPS everywhere, privacy-leveled logging, export compliance declared
  • GAPS: No CRITICAL but HIGH issues present (partial manifest coverage, one HTTP endpoint for non-auth traffic, weak Keychain ACL, missing SSL pinning on payment endpoint)
  • VULNERABLE: Any CRITICAL — hardcoded credentials / missing manifest / ATT without description / missing usage descriptions / tokens in plaintext + HTTP

Output Format

# Security & Privacy Audit Results

## Security & Privacy Map
[5-10 line summary from Phase 1]

## Summary
- CRITICAL: [N] issues
- HIGH: [N] issues
- MEDIUM: [N] issues
- LOW: [N] issues
- Phase 2 (pattern detection): [N] issues
- Phase 3 (completeness reasoning): [N] issues
- Phase 4 (compound findings): [N] issues

## App Store Readiness: READY / NOT READY

## Security Posture
[Phase 5 table]

## Issues by Severity

### [SEVERITY/CONFIDENCE] [Category]: [Description]
**File**: path/to/file.swift:line
**Phase**: [2: Detection | 3: Completeness | 4: Compound]
**Issue**: What's wrong or missing
**Impact**: App Store rejection / security vulnerability / privacy violation
**Fix**: Code example showing the fix
**Cross-Auditor Notes**: [if overlapping with another auditor]

## Privacy Manifest Checklist

| API Category | Found in Code | Declared in Manifest | Status |
|--------------|--------------|---------------------|--------|
| UserDefaults | Y/N | Y/N | OK / MISSING |
| FileTimestamp | Y/N | Y/N | OK / MISSING |
| SystemBootTime | Y/N | Y/N | OK / MISSING |
| DiskSpace | Y/N | Y/N | OK / MISSING |
| ActiveKeyboards | Y/N | Y/N | OK / MISSING |

## Recommendations
1. [Immediate — CRITICAL rejection and security risks]
2. [Short-term — Privacy Manifest completion, Keychain migration, HTTPS]
3. [Long-term — SSL pinning, snapshot protection, analytics anonymization]

Output Limits

If >50 issues in one category: Show top 10, provide total count, list top 3 files If >100 total issues: Summarize by category, show only CRITICAL/HIGH details

False Positives (Not Issues)

  • Secrets in .gitignored config files (verify with Git log)
  • Environment variables in build scripts or CI configs
  • Mock data and fixtures in test files
  • Comments mentioning "key" / "token" / "password"
  • Generic variable names matching credential patterns (e.g., dictionaryKey, mapKey)
  • HTTP URLs in documentation strings, error messages, example text
  • UserDefaults storing non-sensitive preferences (theme, launch count, feature flags)
  • Logger statements with explicit privacy: .private or .sensitive
  • CryptoKit used only for hashing (not encryption) — still check export compliance
  • kSecAttrAccessibleAfterFirstUnlock for tokens that need to survive background fetch (valid trade-off)

Related

For implementation patterns: axiom-shipping skill (privacy manifest creation) For Keychain patterns: axiom-security skill For ATS configuration: axiom-networking skill For entitlement issues: axiom-build skill For IAP-adjacent receipt security: Launch iap-auditor agent

Repository
CharlesWiltgen/Axiom
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.