Skip to content

CounterAudit Integration

RunTimeAdmin edited this page Nov 2, 2026 · 10 revisions

CounterAudit Integration

**Referenced Files in This Document** - [counteraudit-integration.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/docs/counteraudit-integration.md) - [counteraudit.html](https://github.com/RunTimeAdmin/Sigvara/blob/main/site/docs/counteraudit.html) - [ecosystem.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/docs/ecosystem.md) - [SigvaraIdentity.sol](https://github.com/RunTimeAdmin/Sigvara/blob/main/src/SigvaraIdentity.sol) - [SigvaraReputation.sol](https://github.com/RunTimeAdmin/Sigvara/blob/main/src/SigvaraReputation.sol)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Security and Privacy Considerations
  10. Conclusion
  11. Appendices

Introduction

This document explains how CounterAudit integrates with the Sigvara protocol to enrich tamper-evident audit packets with on-chain agent identity and reputation data, and how audit outcomes can be reported back into the Sigvara reputation system. It covers the enrichment workflow, outcome reporting, setup steps for connecting CounterAudit workflows to Sigvara contracts, integration patterns, edge cases, performance guidance, security considerations, and troubleshooting.

The integration provides two complementary directions:

  • Enrichment: CounterAudit reads an agent’s Sigvara identity and reputation at ingest time and seals them inside the AES-GCM-protected packet so the values are frozen at the moment of the action.
  • Outcome reporting: CounterAudit can carry an outcome back to the Sigvara oracle, where it feeds the agent’s Success Rate and Fee Activity factors. Since 1 November 2026 it carries outcomes the payer signed, through their own connector (sigvara-payment-outcome-v1), which needs no allowlist and no oracle token because each operator checks the payer’s signature itself. Its older relay attests an ingest’s outcome and settlement transaction hash with an oracle token, but only for an org listed in CA_OUTCOME_PUBLISH_ORG_IDS. That outcome is the ingesting org’s word, so since 30 October 2026 the production deployment lists no org. A request with neither a token nor the payer’s signature credits the payment and records no outcome.

Project Structure

The relevant repository content for this integration spans documentation, web documentation, and the core Sigvara Solidity contracts:

  • Documentation describing the integration behavior, setup, fields, and forensic properties.
  • A published website page summarizing the same integration for developers.
  • The Sigvara Identity contract that anchors agent identities and exposes identity state.
  • The Sigvara Reputation contract that stores and computes agent scores and thresholds.
graph TB
subgraph "Documentation"
DOC["docs/counteraudit-integration.md"]
SITE["site/docs/counteraudit.html"]
ECO["docs/ecosystem.md"]
end
subgraph "Sigvara Contracts"
ID["src/SigvaraIdentity.sol"]
REP["src/SigvaraReputation.sol"]
end
DOC --> SITE
DOC --> ECO
DOC --> ID
DOC --> REP
SITE --> ID
SITE --> REP
ECO --> ID
ECO --> REP
Loading

Diagram sources

Section sources

Core Components

CounterAudit integration revolves around three main parts:

  1. Ingest API

    • Accepts audit events.
    • Optionally accepts agent_did, outcome, and payment_tx_hash.
    • Takes payer-signed outcomes through the sigvara-payment-outcome-v1 connector, whose raw_event is the body the oracle’s POST /attest takes, and forwards them to the operators.
    • Enriches the event body with Sigvara identity and reputation before sealing.
    • Returns packet_id, entry_hash, and created_at.
  2. Sigvara Identity Contract

    • Stores each registered agent’s operator, address, Ed25519 public key, status, and registration timestamp.
    • Exposes deterministic DID hashing and identity lookup by didHash.
  3. Sigvara Reputation Contract

    • Stores per-agent score factors and computed total scores.
    • Provides threshold checks and matured score computation.
    • Accepts oracle proposals and allows finalization after a challenge window.

Key behaviors:

  • Enrichment is non-blocking: if Sigvara queries fail, the packet still seals normally with agent_identity_verified set to false and an error reason included.
  • Reputation is frozen at seal time: later slashing or score changes do not rewrite historical sealed records.
  • Outcome reporting requires a valid settlement transaction hash because the oracle independently verifies payment rather than trusting the caller. A relayed outcome is recorded only because CounterAudit presents an oracle token (SIGVARA_ORACLE_URL and SIGVARA_ORACLE_TOKEN), and only for an org listed in CA_OUTCOME_PUBLISH_ORG_IDS; the production deployment lists none since 30 October 2026. A payer-signed outcome needs no token: the payer’s signature is the credential.

Section sources

Architecture Overview

The integration connects application code, CounterAudit, and the Sigvara blockchain through a clear flow:

sequenceDiagram
participant App as "Application"
participant CA as "CounterAudit API"
participant ID as "SigvaraIdentity"
participant REP as "SigvaraReputation"
participant ORA as "Sigvara Oracle"
App->>CA : POST /v1/audit/ingest<br/>connector_id, agent_did, raw_event, optional outcome/payment_tx_hash
CA->>ID : getIdentity(didHash)
CA->>REP : getTotalScore(didHash)
ID-->>CA : AgentIdentity
REP-->>CA : Total Score
CA->>CA : Merge Sigvara fields into packet body
CA->>CA : AES-GCM seal + SHA-256 entry hash + RFC 3161 timestamp
CA-->>App : { packet_id, entry_hash, created_at }
alt outcome and payment_tx_hash provided, org listed in CA_OUTCOME_PUBLISH_ORG_IDS (none in production)
CA->>ORA : POST /attest with its oracle token, the outcome and the settlement hash
ORA-->>CA : Oracle acknowledgment
end
Loading

Diagram sources

Detailed Component Analysis

Audit Packet Enrichment Process

When an ingest call includes agent_did, CounterAudit performs these steps:

  1. Parse the DID string in the form did:sigvara:<chainId>:<agentAddress>.
  2. Compute didHash deterministically using the same formula as the on-chain contract.
  3. Read one block (the finalized block by default, set by SIGVARA_BLOCK_TAG), then query SigvaraIdentity.getIdentity(didHash) and SigvaraReputation.getTotalScore(didHash) in parallel, both at that block.
  4. Spread the returned identity and reputation fields into the packet body before applying AES-GCM sealing.
  5. Seal, hash, and timestamp the full packet, including the Sigvara fields.

This guarantees that the reputation score and identity state are frozen at the exact moment of ingestion. The packet also seals agent_chain_snapshot: the chain id, the number and hash of the block both reads used, finality (final for a finalized block, provisional when the node offered only its latest one) and the two contract addresses, so anyone can repeat the reads at that block. Packets sealed before 31 October 2026 carry no snapshot.

flowchart TD
Start(["Ingest Call"]) --> ParseDID["Parse agent_did"]
ParseDID --> ComputeHash["Compute didHash"]
ComputeHash --> ParallelQueries["Query Identity and Reputation in parallel"]
ParallelQueries --> IdentityOK{"Identity Found?"}
IdentityOK --> |No| MarkUnverified["Set agent_identity_verified=false<br/>Include enrichment error"]
IdentityOK --> |Yes| ReadFields["Read status, chain ID, score"]
ReadFields --> MergeBody["Merge Sigvara fields into packet body"]
MarkUnverified --> MergeBody
MergeBody --> Seal["AES-GCM seal + SHA-256 + RFC 3161 timestamp"]
Seal --> Return(["Return packet_id, entry_hash, created_at"])
Loading

Diagram sources

Section sources

Outcome Reporting Mechanism

The outcome relay lets an org’s reported outcome feed back into the agent’s live reputation. It runs only for orgs listed in CounterAudit’s CA_OUTCOME_PUBLISH_ORG_IDS, because the outcome is the ingesting org’s word rather than something CounterAudit checked, and since 30 October 2026 the production deployment lists none. For a listed org:

  • Include outcome with value success or failure.
  • Include payment_tx_hash identifying the settlement transaction.
  • Submit the same ingest payload used for enrichment.

CounterAudit reports the outcome to the Sigvara oracle only after the event is successfully sealed and validated. The oracle re-reads the settlement transaction from the chain and derives the payer from the transfer log; CounterAudit relays the hash but does not control the payment credential. The outcome is recorded because CounterAudit presents an oracle token: a request without one credits the payment and records no outcome. Only successfully sealed, non-duplicate events count toward Success Rate and Fee Activity.

sequenceDiagram
participant App as "Application"
participant CA as "CounterAudit API"
participant CHAIN as "Blockchain"
participant ORA as "Sigvara Oracle"
App->>CA : POST /v1/audit/ingest<br/>agent_did, outcome, payment_tx_hash
CA->>ORA : POST /attest with its oracle token, the outcome and payment.txHash
ORA->>CHAIN : Re-read the settlement transaction
CHAIN-->>ORA : Transfer log confirms payer, amount and block time
ORA-->>CA : Oracle acceptance (outcomeRecorded)
CA-->>App : Sealed packet result
Loading

Diagram sources

Section sources

Payer-Signed Outcomes

Live on Arc testnet since 1 November 2026. An outcome the payer signed (ADR 0006) goes through its own connector, sigvara-payment-outcome-v1. Its raw_event is exactly the body the oracle’s POST /attest takes: the agent’s didHash, the settlement payment.txHash, and the payerOutcome that signPaymentOutcome in @sigvara/protocol-sdk returns.

  • CounterAudit checks the signature against the payer with the SDK’s verifyPaymentOutcome, seals the record whole, and forwards it with no token to each operator listed in its SIGVARA_PAYER_OUTCOME_OPERATORS. The ingest response returns each operator’s answer as forwarded.
  • Sending the same record again asks only the operators that have not taken it, and CounterAudit posts to any one operator at most 30 times a minute. An operator that already holds the outcome answers 409 with sameOutcome: true.
  • CounterAudit sends the packet’s id beside the record as packetId, and the operators serve it as counterauditPacketId. Each of these packets is sealed with a public proof whose outcome_claim.signed_outcome_hash is the EIP-712 hash of what the payer signed, so a reader can recompute that hash from the payerOutcome and payerOutcomeDomain an operator’s /evidence serves and compare.
  • CounterAudit is a courier and a sealer here, not an attester. Each operator checks the payment and the signature again and trusts the payer, not CounterAudit, and the operators import each other’s payer-signed outcomes, so one that takes the post shares it with the rest. They accept "delivered" (outcome: 1) only; "not delivered" waits for a challenge process.

Section sources

Step-by-Step Setup for Connecting CounterAudit Workflows to Sigvara Contracts

Self-hosted CounterAudit

  1. Add environment variables for Sigvara enrichment:

    • SIGVARA_RPC_URL: RPC endpoint for the target chain.
    • SIGVARA_IDENTITY_ADDRESS: Deployed SigvaraIdentity contract address.
    • SIGVARA_REPUTATION_ADDRESS: Deployed SigvaraReputation contract address.
    • SIGVARA_CHAIN_ID: Target chain ID.
    • Optional: SIGVARA_ENRICH_TIMEOUT_MS to control enrichment query timeout, and SIGVARA_BLOCK_TAG, the block both enrichment reads are made at (finalized by default; a node that refuses it falls back to latest, and the snapshot is sealed as provisional).
    • To relay an org’s outcomes back, also set SIGVARA_ORACLE_URL (the oracle’s base URL) and SIGVARA_ORACLE_TOKEN (a write credential the oracle operator issued for CounterAudit), and list the org in CA_OUTCOME_PUBLISH_ORG_IDS. All are needed; without them CounterAudit still enriches packets and relays nothing. Optional: SIGVARA_ORACLE_TIMEOUT_MS, 4000 by default. Payer-signed outcomes need none of these: CounterAudit forwards them to the operators listed in SIGVARA_PAYER_OUTCOME_OPERATORS.
    • On the oracle, the operator issues that credential as an ORACLE_TOKEN_<NAME> variable and can limit it with ORACLE_SCOPES_<NAME>=attest, so a leaked CounterAudit token records outcomes and can do nothing else.
  2. Rebuild and restart the CounterAudit container.

  3. Confirm enrichment is enabled by checking startup logs for the enrichment indicator.

If required variables are missing, CounterAudit silently disables enrichment without breaking existing ingest calls.

Managed CounterAudit

For the managed service, contact CounterAudit to enable Sigvara enrichment against the configured testnet or production network.

Application-side Minimal Change

Add agent_did to your existing CounterAudit ingest payload. If you already use CounterAudit, this is typically the only change needed to start receiving enriched sealed packets.

Section sources

Code Examples for Integrating Reputation Checks into Audit Pipelines

TypeScript Integration Pattern

Use the Sigvara SDK verifier to gate agents before auditing:

  • Check whether an agent meets a minimum reputation threshold using a view call.
  • Reject actions below the threshold before they are audited.
  • For agents above the threshold, submit the audit event with agent_did so CounterAudit freezes the current reputation into the sealed packet.

This pattern keeps low-reputation agents out of sensitive workflows while preserving a tamper-evident record of their activity.

Python Integration Pattern

Send an ingest request with connector_id, agent_did, and raw_event. Handle the response containing packet_id, entry_hash, and created_at. Use the verify endpoint later to decrypt and inspect the enriched packet fields.

Reading Enriched Data

After ingestion, call the verify endpoint with the returned packet_id. The decrypted packet contains:

  • agent_did
  • agent_did_hash
  • agent_chain_id
  • agent_reputation_score
  • agent_identity_status
  • agent_identity_verified
  • agent_enriched_at
  • agent_chain_snapshot, the block both reads were made at, when a block was read
  • Optional agent_enrichment_error when enrichment fails

Section sources

Handling Edge Cases

Scenario Behavior Recommended Handling
Malformed agent_did Enrichment sets agent_identity_verified=false and includes invalid_did_format. Validate DID format client-side; reject or quarantine malformed requests.
Unsupported chain ID Enrichment sets agent_identity_verified=false and includes unsupported_chain:<id>. Ensure the deployed Sigvara contracts match the configured chain ID.
Unregistered DID Enrichment sets agent_identity_verified=false and includes not_registered. Require registration before allowing sensitive actions.
RPC timeout Enrichment sets agent_identity_verified=false and includes rpc_timeout. Increase timeout or add retry/backoff logic; treat as unverified.
RPC failure Enrichment sets agent_identity_verified=false and includes rpc_error. Log errors, monitor health, and fall back to unverified mode.
No block readable Enrichment sets agent_identity_verified=false and includes chain_snapshot_unavailable; neither contract is queried. Check the RPC; treat as unverified.
Agent slashed after sealing Historical sealed packets retain the reputation and status at seal time. Do not assume current status from historical packets; read current state separately if needed.
Duplicate outcome reporting Only successfully sealed, non-duplicate events count. The oracle refuses a settlement already credited with an outcome (409 outcome_recorded). A recorded outcome is final, except that the payer’s own signed outcome can replace a token holder’s within PAYER_OUTCOME_WINDOW_DAYS (14 by default) when the payer’s is the transaction’s only paying leg. For a payer-signed outcome the 409 carries sameOutcome, and heldOutcomeHash when the outcome held is also one the payer signed, so a resend can tell its own outcome, taken before, from a different one. Avoid resubmitting identical outcomes; rely on oracle deduplication.

Section sources

Optimizing Performance

  • Use parallel queries for identity and reputation lookups.
  • Prefer view calls for reputation threshold checks; they are inexpensive and fast.
  • Cache agent eligibility decisions where appropriate, but remember that reputation can change over time.
  • Tune SIGVARA_ENRICH_TIMEOUT_MS based on RPC latency and workload.
  • Avoid reading unbounded operator agent lists directly; use paged access when necessary.

Section sources

Dependency Analysis

The integration depends on both off-chain services and on-chain contracts:

graph LR
APP["Application Code"] --> CA["CounterAudit Service"]
CA --> ID["SigvaraIdentity"]
CA --> REP["SigvaraReputation"]
CA --> ORA["Sigvara Oracle"]
ORA --> REP
REP --> ID
Loading

Diagram sources

Key dependencies:

  • CounterAudit depends on SigvaraIdentity for identity state and on SigvaraReputation for score totals.
  • SigvaraReputation depends on SigvaraIdentity to validate that a score belongs to a registered, non-slashed, bonded agent.
  • Outcome reporting depends on the oracle network to propose and finalize reputation updates.

Section sources

Performance Considerations

  • Enrichment adds RPC calls but remains non-blocking; failures degrade gracefully.
  • Reputation threshold checks are view calls and should be used for pre-gating.
  • Maturity-based score reads are optimized to extrapolate on read rather than requiring constant writes.
  • Operator agent enumeration is unbounded; prefer paged endpoints when scanning many agents.

Troubleshooting Guide

Common Integration Issues

  1. Enrichment Not Enabled

    • Symptom: No Sigvara fields appear in the sealed packet.
    • Cause: Missing SIGVARA_RPC_URL, SIGVARA_IDENTITY_ADDRESS, SIGVARA_REPUTATION_ADDRESS, or SIGVARA_CHAIN_ID.
    • Resolution: Add the required variables and restart the service.
  2. Wrong Chain or Contract Addresses

    • Symptom: unsupported_chain:<id> or identity/reputation queries fail.
    • Cause: Mismatch between configured chain ID and deployed contracts.
    • Resolution: Align SIGVARA_CHAIN_ID with the correct deployment and update contract addresses.
  3. Agent Not Registered

    • Symptom: agent_identity_verified=false with not_registered.
    • Cause: The agent has not completed Sigvara registration.
    • Resolution: Register the agent on Sigvara before ingesting audit events.
  4. RPC Timeouts

    • Symptom: agent_enrichment_error=rpc_timeout.
    • Cause: Slow RPC or insufficient timeout.
    • Resolution: Increase SIGVARA_ENRICH_TIMEOUT_MS or improve RPC reliability.
  5. Outcome Not Affecting Reputation

    • Symptom: Adding outcome does not increase Success Rate or Fee Activity.
    • Cause: Event was rejected, duplicate, or settlement hash could not be verified. Or the ingesting org is not listed in CA_OUTCOME_PUBLISH_ORG_IDS, which is the case for every org on the production deployment since 30 October 2026, or SIGVARA_ORACLE_URL and SIGVARA_ORACLE_TOKEN are not both set; either way CounterAudit relays nothing to the oracle. Or the oracle does not recognise the token, in which case a positive, payment-verified report still credits the payment and no outcome is recorded (outcomeRecorded: false). Or the settlement already carries an outcome, which is final.
    • Resolution: Ensure the event is successfully sealed, the payment_tx_hash is valid and verifiable on-chain, and both oracle variables are set. For an outcome that should count without the relay, have the payer sign it and send it through the sigvara-payment-outcome-v1 connector.
  6. Historical Reputation Appears Stale

    • Symptom: Old packets show a higher reputation than the agent currently has.
    • Cause: Reputation is frozen at seal time; slashing or score drops do not rewrite history.
    • Resolution: Treat historical packets as snapshots; query current state separately if needed.

Section sources

Security and Privacy Considerations

Security

  • Tamper Evidence: All Sigvara-enriched fields are sealed inside AES-GCM. Modifying any field invalidates the seal.
  • Deterministic DID Hash: Anyone can independently verify agent_did_hash using the same formula as the contract.
  • Oracle Trust Model: Outcome reporting relies on the oracle verifying the settlement transaction from the chain rather than trusting the caller-provided payment details. Only the payer’s own signature or a caller holding an oracle token records an outcome, because a settlement hash is public and a stranger who submits one has not shown that they saw the work. For a payer-signed outcome CounterAudit is only the courier: each operator checks the signature against the payer itself.
  • Threshold Gating: Use view-based reputation checks to prevent low-reputation agents from performing sensitive actions.
  • Slash Resilience: Slashed agents cannot be scored back up; historical records remain truthful snapshots.

Privacy

  • Sensitive Audit Data: Keep PII and confidential business data out of raw_event unless absolutely necessary.
  • Minimal Exposure: Only include fields required for auditability and compliance.
  • Access Control: Protect API keys and private keys used for agent operations.
  • Verification vs. Trust: Consumers should verify seals and on-chain state rather than trusting service responses alone.

Section sources

Conclusion

CounterAudit’s integration with Sigvara turns ordinary audit trails into cryptographically anchored, reputation-aware records. By freezing identity and reputation at seal time, and by carrying outcomes the payer signed to every operator, organizations can build defensible AI audit pipelines that combine staked identity, audited behavior, and time-bound reputation signals. Proper setup, careful handling of edge cases, and strong security and privacy practices ensure that the integration remains reliable, verifiable, and resilient.

Appendices

Enriched Field Reference Summary

  • agent_did: W3C DID string.
  • agent_did_hash: Deterministic on-chain index key.
  • agent_chain_id: EVM chain ID from the DID.
  • agent_reputation_score: Frozen total score at seal time.
  • agent_identity_status: Identity state such as Active, PendingBond, Suspended, or Slashed.
  • agent_identity_verified: True when registered and Active.
  • agent_enriched_at: Timestamp of enrichment.
  • agent_chain_snapshot: The chain id, block number and hash, finality (final or provisional) and both contract addresses the reads used, present when a block was read.
  • agent_enrichment_error: Error reason when enrichment fails.

Section sources

Contract-Level View Functions Used by Integration

  • SigvaraIdentity.computeDidHash: Reproduces the canonical DID hash.
  • SigvaraIdentity.getIdentity: Returns identity state for a given didHash.
  • SigvaraReputation.getTotalScore: Returns the spendable, matured score.
  • SigvaraReputation.meetsThreshold: Supports trust gating.

Section sources

Overview

Clone this wiki locally