Security

Scan for secrets, run SAST, and check Kubernetes manifests for misconfigurations.

annave security audit runs one of four scan types against a path or a live Kubernetes cluster. Every finding includes a remediation step.

Usage

bash
annave security audit [path] [flags]

path defaults to . when omitted.

Flags

FlagShortDefaultDescription
--typesecretsScan type: secrets, sast, k8s-live, k8s-local
--formatplainOutput format: plain, json, table
--kubeconfigkubeconfig file path (k8s-live only)
--contextkubeconfig context (k8s-live only)

Scan type: secrets

Walks the directory tree and matches 12 patterns against every non-binary, non-generated file. Skips node_modules, vendor, .git, dist.

RuleWhat it matches
SECRET001AWS access key (AKIA…)
SECRET002AWS secret key assignment
SECRET003GCP service account JSON
SECRET004RSA private key (BEGIN RSA PRIVATE KEY)
SECRET005EC private key
SECRET006Generic PEM private key (BEGIN PRIVATE KEY)
SECRET007JWT secret assignment
SECRET008Generic API token or key assignment
SECRET009Database URL with embedded password
SECRET010GitHub personal access token (ghp_…)
SECRET011Slack token (xoxb-…, xoxp-…)
SECRET012Generic password assignment

Secret scanning does not respect .gitignore. The intent is to find what should not have been committed, including files that may be ignored going forward.

Scan type: sast

Static analysis applied line-by-line to Go and TypeScript source files.

Go rules (GO001–GO010)

RuleWhat it checks
GO001Command injection — `exec.Command` with a variable argument
GO002SQL injection — string concatenation in a query argument
GO003Path traversal — `filepath.Join` or `os.Open` with user input
GO004SSRF — `http.Get` or `http.Post` with a variable URL
GO005Weak random — `math/rand` used for security-sensitive values
GO006Weak crypto — `crypto/md5` usage
GO007Weak crypto — `crypto/sha1` usage
GO008Plaintext HTTP server — `http.ListenAndServe` without TLS
GO009Unbounded read — `ioutil.ReadAll` or `io.ReadAll` without size limit
GO010Unsafe import — `unsafe` package

TypeScript rules (TS001–TS005)

RuleWhat it checks
TS001innerHTML assignment (XSS risk)
TS002dangerouslySetInnerHTML (React XSS risk)
TS003eval() usage
TS004document.write() usage
TS005Sensitive data in localStorage (token, password, secret, key)

Scan type: k8s-live

Connects to the cluster and checks pod specs for security misconfigurations.

RuleWhat it checks
K8S001Container running as root (runAsUser: 0 or no securityContext)
K8S002No CPU limit set
K8S003No memory limit set
K8S004Privileged container (securityContext.privileged: true)
K8S005hostPath volume mount
K8S006Missing readiness probe
K8S007hostNetwork: true or hostPID: true

Scan type: k8s-local

Same 7 rules as k8s-live, applied to YAML manifests in the given path, plus one additional rule:

RuleWhat it checks
K8S008Unpinned image tag — image is `:latest` or has no tag

Examples

Scan for secrets

bash
annave security audit .

SAST on a Go project

bash
annave security audit ./myproject --type sast

Live cluster check

bash
annave security audit --type k8s-live --context production

Local Kubernetes manifests

bash
annave security audit ./k8s --type k8s-local

JSON output, filter high severity only

bash
annave security audit . --format json | jq '[.findings[] | select(.severity == "high")]'

Plain output

text
  Security audit — . [secrets]
  scanned at      2026-05-16 10:42:07
  findings        2
    high          1
    medium        1

  [1] HIGH     SECRET001  AWS Access Key
       file: ./config/deploy.sh:14
       detail: AKIA****************XAMPLE
       fix: Move to environment variable or AWS Secrets Manager

  [2] MEDIUM   SECRET012  Password in source
       file: ./.env.backup:3
       detail: password=pa**...
       fix: Remove from source; use a secrets manager

What to watch

  • SAST rules are line-based pattern matching, not AST analysis. False positives are possible — review each finding before acting.
  • Secret scanning redacts the matched value in plain output (replaces middle characters with *). The full value is never printed.
  • Findings exit with code 0. Non-zero exit only on execution errors (ERR_PERMISSION, ERR_IO_FAILURE, etc.).
  • k8s-live requires list and get on pods cluster-wide.
  • k8s-local processes multi-document YAML files (separated by ---). Each document is checked independently.