Repository navigation
CounterAudit Integration
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Security and Privacy Considerations
- Conclusion
- Appendices
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’soutcomeand settlement transaction hash with an oracle token, but only for an org listed inCA_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.
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
Diagram sources
- counteraudit-integration.md
- counteraudit.html:79-184
- ecosystem.md:144-186
- SigvaraIdentity.sol:22-32
- SigvaraReputation.sol:14-75
Section sources
CounterAudit integration revolves around three main parts:
-
Ingest API
- Accepts audit events.
- Optionally accepts
agent_did,outcome, andpayment_tx_hash. - Takes payer-signed outcomes through the
sigvara-payment-outcome-v1connector, whoseraw_eventis the body the oracle’sPOST /attesttakes, and forwards them to the operators. - Enriches the event body with Sigvara identity and reputation before sealing.
- Returns
packet_id,entry_hash, andcreated_at.
-
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.
-
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_verifiedset 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_URLandSIGVARA_ORACLE_TOKEN), and only for an org listed inCA_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
- counteraudit-integration.md:28-48
- counteraudit-integration.md:249-274
- counteraudit.html:118-184
- SigvaraIdentity.sol:22-32
- SigvaraReputation.sol:14-75
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
Diagram sources
- counteraudit-integration.md:40-48
- counteraudit-integration.md:216-274
- counteraudit.html:159-184
- ecosystem.md:155-183
- SigvaraIdentity.sol:560-566
- SigvaraReputation.sol:696-752
When an ingest call includes agent_did, CounterAudit performs these steps:
- Parse the DID string in the form
did:sigvara:<chainId>:<agentAddress>. - Compute
didHashdeterministically using the same formula as the on-chain contract. - Read one block (the
finalizedblock by default, set bySIGVARA_BLOCK_TAG), then querySigvaraIdentity.getIdentity(didHash)andSigvaraReputation.getTotalScore(didHash)in parallel, both at that block. - Spread the returned identity and reputation fields into the packet body before applying AES-GCM sealing.
- 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"])
Diagram sources
- counteraudit-integration.md:40-48
- counteraudit-integration.md:249-274
- SigvaraIdentity.sol:560-566
- SigvaraReputation.sol:696-752
Section sources
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
outcomewith valuesuccessorfailure. - Include
payment_tx_hashidentifying 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
Diagram sources
Section sources
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 itsSIGVARA_PAYER_OUTCOME_OPERATORS. The ingest response returns each operator’s answer asforwarded. - 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 ascounterauditPacketId. Each of these packets is sealed with a public proof whoseoutcome_claim.signed_outcome_hashis the EIP-712 hash of what the payer signed, so a reader can recompute that hash from thepayerOutcomeandpayerOutcomeDomainan operator’s/evidenceserves 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
-
Add environment variables for Sigvara enrichment:
-
SIGVARA_RPC_URL: RPC endpoint for the target chain. -
SIGVARA_IDENTITY_ADDRESS: DeployedSigvaraIdentitycontract address. -
SIGVARA_REPUTATION_ADDRESS: DeployedSigvaraReputationcontract address. -
SIGVARA_CHAIN_ID: Target chain ID. - Optional:
SIGVARA_ENRICH_TIMEOUT_MSto control enrichment query timeout, andSIGVARA_BLOCK_TAG, the block both enrichment reads are made at (finalizedby default; a node that refuses it falls back tolatest, and the snapshot is sealed as provisional). - To relay an org’s outcomes back, also set
SIGVARA_ORACLE_URL(the oracle’s base URL) andSIGVARA_ORACLE_TOKEN(a write credential the oracle operator issued for CounterAudit), and list the org inCA_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 inSIGVARA_PAYER_OUTCOME_OPERATORS. - On the oracle, the operator issues that credential as an
ORACLE_TOKEN_<NAME>variable and can limit it withORACLE_SCOPES_<NAME>=attest, so a leaked CounterAudit token records outcomes and can do nothing else.
-
-
Rebuild and restart the CounterAudit container.
-
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.
For the managed service, contact CounterAudit to enable Sigvara enrichment against the configured testnet or production network.
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
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_didso 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.
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.
After ingestion, call the verify endpoint with the returned packet_id. The decrypted packet contains:
agent_didagent_did_hashagent_chain_idagent_reputation_scoreagent_identity_statusagent_identity_verifiedagent_enriched_at-
agent_chain_snapshot, the block both reads were made at, when a block was read - Optional
agent_enrichment_errorwhen enrichment fails
Section sources
| 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
- 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_MSbased on RPC latency and workload. - Avoid reading unbounded operator agent lists directly; use paged access when necessary.
Section sources
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
Diagram sources
Key dependencies:
- CounterAudit depends on
SigvaraIdentityfor identity state and onSigvaraReputationfor score totals. -
SigvaraReputationdepends onSigvaraIdentityto 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
- 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.
-
Enrichment Not Enabled
- Symptom: No Sigvara fields appear in the sealed packet.
- Cause: Missing
SIGVARA_RPC_URL,SIGVARA_IDENTITY_ADDRESS,SIGVARA_REPUTATION_ADDRESS, orSIGVARA_CHAIN_ID. - Resolution: Add the required variables and restart the service.
-
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_IDwith the correct deployment and update contract addresses.
- Symptom:
-
Agent Not Registered
- Symptom:
agent_identity_verified=falsewithnot_registered. - Cause: The agent has not completed Sigvara registration.
- Resolution: Register the agent on Sigvara before ingesting audit events.
- Symptom:
-
RPC Timeouts
- Symptom:
agent_enrichment_error=rpc_timeout. - Cause: Slow RPC or insufficient timeout.
- Resolution: Increase
SIGVARA_ENRICH_TIMEOUT_MSor improve RPC reliability.
- Symptom:
-
Outcome Not Affecting Reputation
- Symptom: Adding
outcomedoes 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, orSIGVARA_ORACLE_URLandSIGVARA_ORACLE_TOKENare 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_hashis 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 thesigvara-payment-outcome-v1connector.
- Symptom: Adding
-
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
- counteraudit-integration.md:52-100
- counteraudit-integration.md:263-274
- counteraudit-integration.md:278-299
- counteraudit.html:159-184
- 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_hashusing 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.
-
Sensitive Audit Data: Keep PII and confidential business data out of
raw_eventunless 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
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.
-
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(finalorprovisional) and both contract addresses the reads used, present when a block was read. -
agent_enrichment_error: Error reason when enrichment fails.
Section sources
-
SigvaraIdentity.computeDidHash: Reproduces the canonical DID hash. -
SigvaraIdentity.getIdentity: Returns identity state for a givendidHash. -
SigvaraReputation.getTotalScore: Returns the spendable, matured score. -
SigvaraReputation.meetsThreshold: Supports trust gating.
Section sources
- Agent Registration and Lifecycle
- Contract Overview and Architecture
- Economic Security Model and Incentives
- Evidence Verification and Merkle Proofs
- Key Management and Rotation
- Maturity Mechanism and Score Release
- Proposal Workflow and Challenge System
- Score Storage and Data Model
- SigvaraIdentity Contract
- SigvaraOracleBond Contract
- SigvaraReputation Contract
- SigvaraStaking Contract
- Slashing Lifecycle and Dispute Resolution
- Stake Management Functions
- Status Management and Control
- Token and Fee Contracts
- Unbonding Period and Withdrawal Security
- Anti-Manipulation and Security Measures
- Community Flag Processing
- Evidence Sources and Verification
- External Trust Integration
- Merkle Proof System
- Oracle Score Computation
- Payment-Backed Attestations
- Scoring Model and Formulas
- Agent Creation and Key Management
- Agent Operations
- Agent Registration Workflow
- Challenge-Response Authentication
- Gate Access Control
- Integration Patterns and Examples
- SDK Overview and Setup
- Verifier Functions