Skip to content

Security and Safety

Anna edited this page Jun 25, 2026 · 1 revision

Security & Safety

For a high-level overview of what's safe by default with no configuration, see Safety & Cost Safeguards. This page covers technical implementation details: HITL flow, PII scrubbing, rate limits, and IAM roles.

Aura Tracker GCP is designed on the principle that the LLM proposes, you approve. No mutation reaches GCP without an explicit human confirmation step.


Human-in-the-Loop Mutations

Two tools can change GCP state:

Tool What it changes
gcp_gke_scale_deployment GKE node pool size
gcp_cloudrun_update_traffic Cloud Run traffic split percentages

Both are protected by a two-step confirmation flow enforced at the server level — the LLM cannot bypass it.


Two-Step Confirmation Flow

Step 1 — Preview
─────────────────────────────────────────────────
  LLM calls tool with dry_run=true
        ↓
  Server previews the change (no GCP API call made)
  Returns: plan_id, human-readable description, expires_in=10min
        ↓
  LLM presents the preview to YOU
        ↓
  ★ YOU decide: approve or reject ★

Step 2 — Execute (only after your explicit approval)
─────────────────────────────────────────────────
  LLM calls tool with confirm_plan_id=<plan_id>
        ↓
  Server validates the plan (not expired, not already used)
  Atomically consumes the plan (single-use)
  Executes the mutation against GCP
  Logs confirmation at WARN level with full audit context

Diagram suggestion: A UML sequence diagram with four actors: User, LLM, Aura Tracker GCP Server, GCP APIs. Show Step 1 ending at the User with a decision diamond, and Step 2 only proceeding if the user says "yes". Highlight the 10-minute TTL expiry window.

Key safety properties:

  • Plans expire after 10 minutes. A stale plan_id is rejected with an actionable error message.
  • Each plan_id is single-use — atomically consumed on confirmation, preventing replay attacks.
  • Both dry-run and confirmation are logged. Log entries include project, resource, previous state, and requested change.
  • SAFETY_ENABLED=false disables the confirmation gate. Use only in development environments — the server logs a WARNING on startup when this flag is set.

PII Scrubbing (Anonymization Engine)

The anonymization engine runs as middleware on every tool result, applied before the LLM sees the output. It is off by default.

Enable

ANONYMIZE_ENABLED=true GCP_PROJECT_ID=my-project ./aura-tracker-gcp

With a Config File

ANONYMIZE_ENABLED=true \
ANONYMIZE_CONFIG_PATH=/path/to/anonymize.yaml \
GCP_PROJECT_ID=my-project ./aura-tracker-gcp

Built-in Detection Patterns

Pattern name What it matches
internal_ip Private IPv4 ranges: 10.x, 172.16-31.x, 192.168.x
public_ip Any valid IPv4 address
email Standard email format
service_account GCP service accounts (*@*.iam.gserviceaccount.com)
gcp_api_key GCP API keys (39-char AIza… prefix)

Custom patterns can be appended via the patterns: list in your YAML config.

Stable Token Replacement

The same raw value always maps to the same token within a single tool call (e.g., the first matching email becomes [EMAIL_1], the second [EMAIL_2]). This lets the LLM reason about correlations (same service account appears in two places) without ever seeing the actual value.

Audit Mode

Set audit_only: true in the YAML config to see exactly which patterns would fire and on which JSON paths — without masking anything. Use this to tune your patterns safely before enabling real scrubbing.

# anonymize.yaml
audit_only: true
patterns:
  - name: internal_project_id
    regex: "proj-[a-z0-9]{8}"

Rate Limiting & Timeouts

Every GCP API call is throttled at the server boundary, not the tool level. The LLM cannot generate more API traffic than these limits allow.

Limit Value
Rate limit 10 requests/second
Burst capacity 20 requests
Per-call timeout 30 seconds
Fan-out budget 30 seconds shared across parallel goroutines (e.g., gcp_gke_get_cluster_bottlenecks)

These protect your GCP quota and prevent runaway costs from a looping agent.


Least-Privilege IAM Guide

Aura Tracker GCP needs read permissions for almost all tools. Only the two mutation tools need write access.

Read-Only Role Set

roles/container.viewer            # GKE clusters, node pools
roles/run.viewer                  # Cloud Run services, jobs
roles/pubsub.viewer               # Pub/Sub topics, subscriptions
roles/logging.viewer              # Cloud Logging
roles/monitoring.viewer           # Cloud Monitoring, Cloud Trace
roles/iam.securityReviewer        # IAM bindings, policy reads
roles/storage.objectViewer        # Cloud Storage buckets and objects
roles/cloudsql.viewer             # Cloud SQL instances
roles/secretmanager.viewer        # Secret Manager metadata only
roles/cloudtasks.viewer           # Cloud Tasks queues
roles/cloudscheduler.viewer       # Cloud Scheduler jobs
roles/workflows.viewer            # Cloud Workflows
roles/eventarc.viewer             # Eventarc triggers
roles/vpcaccess.viewer            # Serverless VPC Access connectors
roles/compute.networkViewer       # VPCs, subnets, load balancers
roles/artifactregistry.reader     # Artifact Registry repos and images
roles/cloudbuild.builds.viewer    # Cloud Build triggers

Additionally for Mutation Tools

roles/container.nodePoolAdmin     # gcp_gke_scale_deployment
roles/run.admin                   # gcp_cloudrun_update_traffic

Verify Effective Permissions

Before relying on the server, run:

"Test my IAM permissions for project my-project"

This calls gcp_iam_test_permissions, which returns a per-permission allowed: true/false result for every relevant GCP API the server needs.

Best practice: Create a dedicated service account with only the roles listed above. Never run this server with roles/owner or roles/editor.


What Aura Tracker GCP Never Does

Never Why
Reads Secret Manager values Only secret metadata (name, labels, create time) is fetched
Stores data externally Results flow directly from GCP to your LLM; nothing is persisted outside your environment
Executes mutations without a confirmed plan_id The SafetyDecorator in internal/safety/decorator.go enforces this at the port boundary
Initializes unused GCP clients Only clients needed for your enabled --modules set are instantiated, minimizing the OAuth token scope
Contacts any endpoint outside GCP APIs The server makes no outbound calls except to GCP service endpoints

Clone this wiki locally