Investigation Cost Guardrail logo

Investigation Cost Guardrail

Organization
aws
investigation-cost-guardrail

Cost guardrail for AWS DevOps Agent that covers ALL AWS services and native agent tools. Before the agent makes any paid API call, this skill estimates cost, enforces budgets per investigation, detects expensive operations across all services (Athena queries, S3 scans, DynamoDB scans, SageMaker inference, PromQL, etc.), enforces time window requirements, monitors cumulative call volume, and cancels if thresholds are exceeded. This skill applies to ALL investigations regardless of which services are involved.

Overview

Publisheraws
Repositorytools-for-devops-agent
Skill nameinvestigation-cost-guardrail
Stars
120
Forks
97
Bundled files
7
LicenseApache-2.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 7 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by aws on GitHub. Read the source before you install it.

Installation

Install the Investigation Cost Guardrail AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/aws/tools-for-devops-agent/tree/main/skills/investigation-cost-guardrail
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/aws/tools-for-devops-agent.git /tmp/tools-for-devops-agent
mkdir -p .claude/skills
cp -r /tmp/tools-for-devops-agent/skills/investigation-cost-guardrail .claude/skills/investigation-cost-guardrail
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Investigation Cost Guardrail in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Investigation Cost Guardrail on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Investigation Cost Guardrail is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Investigation Cost Guardrail Skill

Overview

This skill provides cost guardrails for ANY AWS service and ALL native agent tools — not just a hardcoded list. It uses heuristic classification to determine whether an API operation is free or paid, estimates cost before execution, and enforces per-investigation budgets.

Design Principle

Rather than listing every free/paid operation across 200+ AWS services, this skill uses three layers:

  1. Heuristic rules — classify any operation based on naming patterns and behavior
  2. Known-paid registry — explicit overrides for high-cost operations with pricing formulas
  3. Response validation — detect metered usage from API response fields after execution

Activation

This skill MUST be ALWAYS ACTIVE during investigations. It does NOT require user invocation.

Fetch Live Rate Before Estimating

The first time an operation is classified PAID by Layer 2, fetch the live rate before estimating cost.

For AWS operations: read references/pricing-reference.md for the exact Pricing API call patterns, filter fields, filter values, and failure handling. The reference file specifies — for each service and operation — whether to use Field:"operation" or Field:"usagetype", and the exact value to use. Do not derive these from the operation name.

For non-AWS tools (Splunk, Datadog, Grafana, etc.): use the cost model from Layer 0 directly — no live lookup available.


Layer 0: Native Agent Tool Classification

Before Layer 1 heuristics, classify the agent's own tools. These are NOT use_aws calls but have distinct billing implications:

Tool Cost Matrix

ToolClassificationCost ModelGuardrail
get_prometheus_metricsPAIDBilled per sample scanned — rate from live CW:PromQL:SamplesScanned usagetype lookup (AmazonCloudWatch, workload-region prefix)Track samples scanned per call; HALT if rate lookup returns 0 products
use_awsVARIABLEDepends on operation — apply Layers 1–3Full heuristic pipeline
use_azureFREEAzure Reader role, no per-call billingTrack count only
grafana_query_prometheusCAUTIONDepends on Grafana data source billing modelTrack count, warn at 50+
use_datadogCAUTIONDatadog API rate limits (no per-call $ cost, but may throttle)Track count, warn at 100+
use_splunkPAIDSplunk search license (per GB ingested/searched)Treat like CW Logs StartQuery
use_pagerdutyFREEPagerDuty API (rate limited, not per-call billed)Track count only
shellCAUTIONMay invoke aws, az, kubectl — untracked by Layers 1–3Log commands, warn if aws/az detected
subagentPAIDCounts toward agent-seconds billing ($0.0083/sec)Track spawns, enforce total time
fs_read, fs_write, fs_treeFREELocal file I/ONo guardrail needed
datetimeFREEInternal state opsNo guardrail needed
write_scratchpad, read_scratchpadFREEInternal state (may not be available in all environments)No guardrail needed
read_memoriesFREEInternal memory recallNo guardrail needed

PromQL-Specific Controls

get_prometheus_metrics deserves special handling because:

  • Maximum 500 series per query — a broad query hitting the cap costs 500 × rate per period.
  • Range queries with small step multiply cost: 7d / 60s step = 10,080 datapoints × 500 series = 5M samples

Before each PromQL call:

text
rate = live usagetype lookup (AmazonCloudWatch, usagetype=<PREFIX>-CW:PromQL:SamplesScanned)
       # bare "CW:PromQL:SamplesScanned" for us-east-1; use workload-region prefix for all others
if rate lookup returns 0 products: 🚫 HALT — do not hardcode or improvise a rate

estimated_samples = min(500, estimated_series) × (time_range_seconds / step_seconds)
estimated_cost = estimated_samples × rate

if estimated_cost > $0.50:
    ⚠️ WARN — suggest narrower time range, larger step, or label filters
if estimated_cost > $2.00:
    🚫 HALT — require approval or suggest aggregation (sum, topk, avg)

Cost reduction for PromQL:

  • Use sum by (label) to reduce series count
  • Use topk(N, ...) to cap returned series
  • Increase step (300s instead of 60s = 5× cheaper)
  • Narrow time range (1h instead of 7d = 168× cheaper)

Layer 1: Heuristic Classification

Before making ANY use_aws call, classify the operation using these rules IN ORDER:

Rule 1: FREE by default — Metadata operations

An operation is FREE if it matches ALL of these:

  • Verb is: Describe, List, Get, Lookup, Check, Validate, Tag, Untag
  • It returns metadata/configuration (not data content or query results)
  • It does NOT scan, process, or transform customer data

⚠️ Exception: Some services charge per-request even for Get/List operations. Layer 2 overrides this heuristic for S3 and Lambda Invoke — when Layer 2 has an entry, it takes precedence over Rule 1.

⚠️ Tool policy can override cost classification. Some operations classified as FREE here (e.g., cloudtrail:LookupEvents) may be blocked by tool policy in certain environments. If an operation is denied, it costs $0.00 (never executed) — proceed with alternatives.

Rule 2: PAID — Data-scanning operations

An operation is PAID if it matches ANY of these patterns:

PatternWhy It Costs MoneyExamples
Verb contains QueryScans indexed dataStartQuery, StartQueryExecution
Verb contains ScanFull table/index scanScan (DynamoDB), StartScan
Verb contains Execute + processes dataRuns a computationStartQueryExecution (Athena), ExecuteStatement
Verb contains Invoke + runs workloadTriggers computeInvokeEndpoint (SageMaker), Invoke (Lambda)
Operation reads content (not metadata)Data transferGetObject (S3, large), GetLogEvents (bulk), BatchGetTraces
Operation starts a streaming sessionPer-time billingStartLiveTail
Operation name contains InsightsAnalytics processingGetContributorInsights, GetInsightRuleReport

Rule 3: CAUTION — High-volume free operations

An operation is FREE but CAUTION if:

  • It's a paginated List/Describe that could return thousands of results
  • It has no built-in limit and the scope is broad (e.g., all resources in a region)

Examples: ListObjectsV2 (large bucket), ListMetrics (unfiltered), DescribeTasks (large cluster)

Rule 4: UNKNOWN — Cannot classify

If an operation doesn't clearly fit Rules 1–3:

  • Treat as CAUTION (proceed but track)
  • After execution, check response for metered fields (see Layer 3)
  • If metered: add to the known-paid list for this session

Layer 2: Known-Paid Registry

These operations have confirmed pricing. Before estimating, fetch the live rate via the Pricing API using the exact filter field and value from the table below — see references/pricing-reference.md for the bash call patterns and region prefix mapping.

Critical lookup rule: usagetype and operation are different Pricing API filter fields. The correct field and value for each operation are specified explicitly below — do NOT derive them from the operation name.

Pricing Lookup Rules

text
if len(products) == 0:
    🚫 HALT — Pricing lookup returned no results for <ServiceCode>:<Operation>
    Reason: filter field/value or workload-region prefix may be incorrect
    Do NOT proceed with the paid operation.
    Do NOT improvise a rate from memory, training data, or any other source.
    Options:
      → Re-check pricing-reference.md for the correct filter field, value, and region prefix
      → Skip this operation and use a free alternative
      → Report the lookup gap to the user

Confirmed Paid Operations

Rate = pricePerUnit.USD from terms.OnDemand → priceDimensions where beginRange="0". No /1K or /1M divisors. Region scoping: see Region Scoping column.

ServiceCodeLayer 2 OperationPricing API Filter FieldFilter ValueRegion scopingCost FormulaEstimation Method
AmazonCloudWatchGetMetricDataoperationGetMetricData+ regionCode=<workload-region>(metrics × periods) × rateCount metrics and periods
AmazonCloudWatchStartQueryoperationStartQuery+ regionCode=<workload-region>scan_gb × rateQuery IncomingBytes metric for time window
AmazonCloudWatchStartLiveTailoperationStartLiveTail+ regionCode=<workload-region>Duration-basedDuration-based
AmazonCloudWatchGetInsightRuleReportusagetypeCW:GIRR-Metricsworkload-region prefix required (bare in us-east-1)metrics_requested × rateCount metrics requested in the report call
AmazonCloudWatchget_prometheus_metrics (native tool)usagetypeCW:PromQL:SamplesScannedworkload-region prefix required (bare in us-east-1)samples_scanned × rateEstimate min(500, series) × (range_seconds / step_seconds)
AWSXRayGetTraceSummariesoperationXRay-Traces-Scanned+ regionCode=<workload-region>traces × ratePaginate or sample to estimate count
AWSXRayBatchGetTracesoperationXRay-Traces-Retrieved+ regionCode=<workload-region>traces × rateCount trace IDs in request
AmazonAthenaStartQueryExecutionusagetypeDataScannedInTBworkload-region prefix required (USE1- for us-east-1)scan_tb × rate; min 10MBCheck table metadata; require WHERE clause
AmazonDynamoDBScanusagetypeReadRequestUnitsworkload-region prefix required (bare in us-east-1, no USE1-)RCU consumed × rateCheck TableSizeBytes; BLOCK unless user approves
AmazonDynamoDBQueryusagetypeReadRequestUnitsworkload-region prefix required (bare in us-east-1, no USE1-)RCU consumed × rateCheck ItemCount; warn if > 10K items
AmazonS3GetObjectusagetypeRequests-Tier2workload-region prefix required (bare in us-east-1)See pricing-reference.mdCount requests; flag if cross-region or >100MB
AmazonS3ListObjectsV2, ListObjectsusagetypeRequests-Tier1workload-region prefix required (bare in us-east-1)See pricing-reference.mdCount calls; warn if paginating heavily
AmazonS3PutObject, CopyObjectusagetypeRequests-Tier1workload-region prefix required (bare in us-east-1)See pricing-reference.mdCount calls
AmazonS3SelectObjectContentusagetypeBills on 3 meters — see pricing-reference.mdworkload-region prefix required (bare in us-east-1)See pricing-reference.mdCheck object size
AmazonSageMakerInvokeEndpoint————BLOCK — require explicit user approval
AWSLambdaInvoke———Per request + computeBLOCK unless user explicitly requests function execution

Layer 3: Response Validation

After ANY operation executes, check the response for metered fields:

Metered Response Fields (indicates cost was incurred)

Field PatternMeaningAction
BytesScanned, DataScannedData scanning chargeRecord GB scanned, add to running cost
RecordsProcessed, ItemCountRecord processingRecord count, estimate RCU/cost
QueryExecutionId + DataScannedInBytesAthena scanAdd to cost at live rate
TracesProcessedCountX-Ray processingAdd to cost at live rate
ConsumedCapacityDynamoDB RCU/WCUAdd to cost at live rate
ContentLength > 100MBLarge object fetchFlag for transfer cost
NextToken after 10+ pagesPagination runawayTrigger volume guardrail
warnings containing "500 series"PromQL truncationFlag max-cost query, suggest narrowing

If a previously-unclassified operation returns metered fields:

  1. Log it as a paid operation for this session
  2. Add the cost to the running total
  3. Warn the user: ⚠️ Discovered paid operation: <servicecode>:<operation> cost $X.XX

Budget Enforcement

Per-Investigation Budget

The agent MUST mentally track a running cost estimate throughout the investigation. Since write_scratchpad/read_scratchpad are not available in all environments, budget enforcement is behavioral — the agent maintains the accumulator in its context window.

At investigation start:

text
Budget: $10.00
Running cost: $0.00
Call counts: {}

Before each PAID operation:

text
estimated_cost = estimate(operation)
if running_cost + estimated_cost > budget:
    🚫 HALT — show budget display
else:
    proceed
    # After execution:
    running_cost += actual_cost (from response fields or estimation)
    call_counts[servicecode] += 1

Volume guardrails:

text
if call_counts[any_servicecode] > 200: ⚠️ WARN
if call_counts[any_servicecode] > 500: 🚫 HALT
if sum(all_call_counts) > 1000: 🚫 HALT

ℹ️ If write_scratchpad becomes available in your environment, use it for persistent state across subagent boundaries. Check with: search_user_tools("scratchpad"). If found, store {budget, running_cost, call_counts} as JSON.

Budget Display (on halt)

text
📋 INVESTIGATION BUDGET STATUS
════════════════════════════════════════════════════════════
Budget:      $10.00
Spent:       $X.XX (Y paid operations)
Free calls:  Z operations (no cost)
PromQL:      X,XXX samples scanned ($X.XX)
Next op:     <servicecode>:<operation> — estimated $X.XX
Projected:   $X.XX (exceeds budget by $X.XX)

🚫 HALTED — would exceed $10.00 budget.
💡 Options:
  → Approve additional $X.XX to continue
  → Narrow the time window to reduce scan volume
  → Skip this operation and continue with free alternatives
  → End investigation with findings so far

Time Window Enforcement

For ANY operation classified as PAID that scans data over a time range:

ScenarioAction
User provided time window✅ Use it — estimate cost for that window
No time window, operation scans data🚫 CANCEL — show worst-case cost, ask for window
No time window, operation is bounded (single resource lookup)✅ Proceed — no scan involved

Key distinction: "Get me the config of Lambda X" (bounded, free) vs. "Search logs for errors" (unbounded scan, needs window).

PromQL-specific: Range queries without explicit start/end default to "now" which is safe. But broad label selectors ({} with just metric name) can hit 500 series cap — always prefer specific labels.


Cross-Region Detection

For EVERY paid operation:

text
if target_region ≠ agent_space_region:
    fetch transfer_rate = transfer_rate_cache[target_region]
                       ?? live lookup (see references/pricing-reference.md)
    # If the live lookup returns 0 products: 🚫 HALT — do NOT improvise a rate
    estimated_return_size = estimate_return_bytes(operation_type)
    transfer_cost = estimated_return_size × transfer_rate
    total_estimate += transfer_cost
    flag: "⚠️ Cross-region transfer: <target> → <agent_space>"

Return size heuristics:

  • Aggregation queries (stats, count, group-by): ~KB (negligible)
  • PromQL with aggregation (sum, topk): ~KB (negligible)
  • PromQL range query (500 series × 10K points): ~50MB (flag ⚠️)
  • Raw log/trace fetches: up to 100% of matched bytes
  • Describe/List results: ~KB (negligible)
  • Unknown: use 15% of scan volume as upper bound, flag ⚠️

Cost Reduction Suggestions

When halting or warning, ALWAYS suggest free or cheaper alternatives:

Generic Alternatives (apply to any service)

PatternFree/Cheaper Alternative
Broad time window scanNarrow to ±30 min around the incident
Multiple resource queryTarget specific resource ID
Full scan (DynamoDB, Athena)Add filter/WHERE/key condition
Analytics query for known stringUse free filter API (FilterLogEvents) — note: LookupEvents may be tool-policy-blocked in some environments
Cross-region operationSuggest user run from workload region
Large object fetchUse SelectObjectContent with SQL filter
Pagination explosionAdd limit, filter, or narrower scope
Broad PromQL (no label filters)Add specific label matchers or use aggregation
PromQL small step (60s over 7d)Increase to 300s+ or reduce time range

Service-Specific Alternatives

Instead of...Use...Savings
logs:StartQuerylogs:FilterLogEvents (if searching for known string)100%
cloudwatch:GetMetricData (many)cloudwatch:GetMetricStatistics (single)~100%
get_prometheus_metrics (broad)Add sum by (label) or topk(5, ...)90%+
dynamodb:Scandynamodb:Query with key condition~100%
athena:StartQueryExecution (full)Add partition filter in WHERE90%+
xray:GetTraceSummaries (broad)Narrow time + add filter expression90%+
s3:GetObject (large)s3:SelectObjectContent with SQLVariable

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Investigation Cost Guardrail AI skill do?

Cost guardrail for AWS DevOps Agent that covers ALL AWS services and native agent tools. Before the agent makes any paid API call, this skill estimates cost, enforces budgets per investigation, detects expensive operations across all services (Athena queries, S3 scans, DynamoDB scans, SageMaker inference, PromQL, etc.), enforces time window requirements, monitors cumulative call volume, and cancels if thresholds are exceeded. This skill applies to ALL investigations regardless of which services are involved.

Why use Investigation Cost Guardrail on TypingMind?

Because you install it once and use it with any model. Investigation Cost Guardrail is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Investigation Cost Guardrail in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/aws/tools-for-devops-agent/tree/main/skills/investigation-cost-guardrail. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Investigation Cost Guardrail?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Investigation Cost Guardrail?

As many as you like. As long as a model supports skills, you can use Investigation Cost Guardrail with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Investigation Cost Guardrail AI skill free?

Yes. It is published on GitHub by aws under the Apache-2.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇