1-SEC contributors · Reviewed · Module: ai_containment

Agent Payment Telemetry: x402 Labels and Recipient Risk Signals

AI Containment consumes reported payment metadata and flags selected risk signals.

What 1-SEC checks

AI Containment consumes reported payment metadata and flags selected risk signals. It compares one parsed amount with a positive reported limit, recognizes a missing delegated_by string, notes a first recipient within the current agent window and matches recipient substrings such as drainer or scam. A ten-minute per-agent profile counts all reported payments and sums raw amounts; more than ten events or a raw total above one thousand produces a rapid-spending signal. The x402 event name supplies a protocol label, not a settlement verifier.

Read the implementation: handleAgentPayment

Required telemetry and context

Relevant input events: agent_payment, x402_payment. Use a trusted producer at the real application boundary.

  • agent_id
  • amount (string)
  • recipient
  • currency
  • protocol
  • merchant_id
  • delegated_by
  • spending_limit (string)

Field names above describe relevant context, not a complete API request. Consult the current event contract for envelope and detail requirements. Preserve booleans, numbers, and strings as the receiving handler expects them. Agent-provided text cannot independently verify identity or authorization.

Deployment, prevention, and response

Emit only trusted, consistently typed metadata from the payment integration and keep actual tokens, keys and transaction authorization outside model text. Independently enforce wallet budgets, verified approvals, recipient validation and idempotency in the real payment service. Investigate a substring or first-recipient alert with provider evidence rather than blocking on an uncalibrated fraud label alone. Use the inert metadata fixtures to verify alerts before enabling any response; never send funds to test the scanner.

Record the source event, affected agent/host, actual target, policy decision, and response result. Review enforcement configuration separately from detection. A recommendation, selected action, dry-run record, and completed action are different outcomes.

Reproduce the source fixtures

From a checkout of the linked 1-SEC source revision, run the selected fixtures with the repository's Go toolchain. These commands run tests; they do not execute a real attack against your systems.

go test ./internal/modules/aicontainment -run '^(TestContainment_PaymentMetadataSignals|TestAgentPaymentMonitor_WindowAndPolicyLimits)$' -count=1

New fixtures verify the real handler with ordinary, over-reported-limit, missing-principal and suspicious-recipient metadata. The state fixture demonstrates mixed-currency totals, presence-only principal text and window-reset history. No money, wallet, provider account, HTTP payment challenge or blockchain settlement is exercised.

TestContainment_PaymentMetadataSignals

Full fixture and assertions — run in its original package with its helpers.

func TestContainment_PaymentMetadataSignals(t *testing.T) {
	for _, tc := range []struct{ name, amount, recipient, principal, alert string }{
		{"ordinary reported payment", "5", "merchant.example", "reported-owner", ""},
		{"over reported limit", "51", "merchant.example", "reported-owner", "agent_spending_limit"},
		{"missing principal text", "5", "merchant.example", "", "agent_payment_no_delegation"},
		{"recipient substring", "5", "sample-drainer", "reported-owner", "agent_suspicious_recipient"},
	} {
		t.Run(tc.name, func(t *testing.T) {
			cp := makeCapturingPipeline()
			c := startedModuleWithPipeline(t, cp)
			defer c.Stop()
			e := core.NewSecurityEvent("test", "x402_payment", core.SeverityInfo, "inert metadata fixture")
			e.Details = map[string]interface{}{"agent_id": "payer", "amount": tc.amount, "spending_limit": "50", "recipient": tc.recipient, "delegated_by": tc.principal, "currency": "USDC"}
			if err := c.HandleEvent(e); err != nil {
				t.Fatal(err)
			}
			if tc.alert != "" && !cp.hasAlertType(tc.alert) {
				t.Fatalf("expected %s", tc.alert)
			}
			if tc.alert == "" && (cp.hasAlertType("agent_spending_limit") || cp.hasAlertType("agent_payment_no_delegation") || cp.hasAlertType("agent_suspicious_recipient")) {
				t.Fatal("ordinary metadata produced a risk alert")
			}
			if !cp.hasAlertType("agent_new_recipient") {
				t.Fatal("first recipient was not observed")
			}
		})
	}
}
TestAgentPaymentMonitor_WindowAndPolicyLimits

Full fixture and assertions — run in its original package with its helpers.

func TestAgentPaymentMonitor_WindowAndPolicyLimits(t *testing.T) {
	pm := NewAgentPaymentMonitor()
	pm.RecordPayment("payer", "40", "merchant", "USDC", "x402", "", "unverified-text", "50")
	second := pm.RecordPayment("payer", "40", "merchant", "OTHER", "other", "", "unverified-text", "50")
	if second.SpendingLimitExceeded || second.NoDelegation || second.NewRecipient || second.TotalSpent != 80 {
		t.Fatalf("expected per-event comparison and presence-only principal, got %+v", second)
	}
	pm.mu.Lock()
	profile, _ := pm.agents.Get("payer")
	profile.PaymentWindow = time.Now().Add(-11 * time.Minute)
	pm.mu.Unlock()
	next := pm.RecordPayment("payer", "1", "merchant", "USDC", "x402", "", "unverified-text", "50")
	if !next.NewRecipient || next.PaymentCount != 1 || next.TotalSpent != 1 {
		t.Fatalf("recipient and totals should reset with the window: %+v", next)
	}
}

Tuning, evaluation, and coverage limits

These signals do not establish payment fraud, wallet authorization, sanctions screening or x402 protocol verification. The payment handler accepts any nonempty delegated_by text without checking the separate verified-delegation tracker. Its limit is supplied in each event and compared per payment, not enforced cumulatively against a protected balance. Floating-point totals mix currencies and protocols, and recipient history resets with the window. Failed/retried/settled states and transaction idempotency are not classified. Malformed amounts can parse as zero or a numeric prefix. No payment or wallet action is executed by this handler.

Evaluate this behavior with representative authorized activity and a controlled known-positive case. Investigate the exact rule, inputs, and state before suppressing an alert. Do not assume a hard-coded heuristic is a configurable setting. Measure your own deployment; the source fixtures do not establish a benchmark, detection rate, compliance certification, or incident-prevention claim.

Protocol and format references

These references describe the underlying format or protocol. The implementation and fixtures above define the subset 1-SEC actually checks.

Related implemented controls

Implementation reviewed at source revision 4803febcb2bfe646bb74d1bf0f8f4e7fe8a880a6. Recheck the actual release and integration before deployment. Sources and corrections policy.