Sorcha.Agent 2.17.1

There is a newer version of this package available.
See the version list below for details.
dotnet tool install --global Sorcha.Agent --version 2.17.1
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Sorcha.Agent --version 2.17.1
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Sorcha.Agent&version=2.17.1
                    
nuke :add-package Sorcha.Agent --version 2.17.1
                    

Sorcha Agent - Autonomous Actor for Decentralised Workflows

Version: 1.0.0 Status: Production Ready

The Sorcha Agent is a cross-platform CLI tool that runs as an autonomous actor in Sorcha decentralised register workflows. It listens for pending actions, makes decisions using pluggable engines (rules or AI), and submits responses — enabling fully automated multi-participant workflow execution.

Installation

# Install as a global tool
dotnet tool install --global Sorcha.Agent

# Verify installation
sorcha-agent --version

Quick Start

1. Create an Actor Definition

Actor definitions are JSON files that configure identity, inbox discovery, and decision-making:

{
  "actor": {
    "name": "approver",
    "description": "Automated approval agent"
  },
  "connection": {
    "gatewayUrl": "http://localhost",
    "registerId": "your-register-id",
    "credentials": {
      "email": "$env:AGENT_EMAIL",
      "password": "$env:AGENT_PASSWORD",
      "organizationId": "your-org-id"
    },
    "walletAddress": "your-wallet-address"
  },
  "inbox": {
    "signalR": { "enabled": true },
    "polling": { "enabled": true, "intervalSeconds": 30 }
  },
  "mode": "rules",
  "rules": [
    {
      "actionName": "Review Request",
      "condition": { "==": [true, true] },
      "decision": "approve",
      "payload": {
        "approved": true,
        "notes": "Auto-approved by agent"
      }
    }
  ]
}

2. Validate Configuration

sorcha-agent validate --config actor.json

This checks JSON structure, variable resolution, authentication, and SignalR connectivity.

3. Run the Agent

sorcha-agent run --config actor.json

The agent will authenticate, connect to the inbox, and begin processing actions autonomously.

Commands

Command Description
sorcha-agent run --config <path> Start the autonomous actor loop
sorcha-agent validate --config <path> Pre-flight configuration checks
sorcha-agent haip receive --offer-uri <uri> Receive a credential via OID4VCI pre-authorized code flow
sorcha-agent haip present --request-uri <uri> Present a credential via OID4VP direct_post

Options

Option Description
--config Path to actor definition JSON (required)
--state Path to state.json for placeholder resolution
--verbose Enable debug-level logging
--quiet Errors only

HAIP Wallet Commands

The agent can act as a simulated HAIP wallet for end-to-end testing of OpenID4VCI and OpenID4VP flows. These commands are standalone (they do not use actor JSON files or the autonomous loop) and operate on a local file-based wallet directory.

Receive a Credential (OpenID4VCI)

sorcha-agent haip receive --offer-uri <uri> --wallet-dir ./wallet

Executes the OID4VCI pre-authorized code flow:

  1. Parses the openid-credential-offer:// URI to extract the offer JSON
  2. Fetches issuer metadata from /.well-known/openid-credential-issuer
  3. Exchanges the pre-authorized code for an access token and c_nonce
  4. Builds a JWT proof of possession binding the holder key to the nonce
  5. Requests the credential at the credential endpoint
  6. Stores the SD-JWT VC in <wallet-dir>/credentials/<CredentialType>.sdjwt
Option Required Default Description
--offer-uri Yes - OpenID4VCI Credential Offer URI
--wallet-dir No ./wallet Directory for keys and credentials
--key-file No <wallet-dir>/holder-key.pem Path to holder key PEM file

Present a Credential (OpenID4VP)

sorcha-agent haip present --request-uri <uri> --credential VerifiedIdentityCredential --disclose "givenName,familyName,dateOfBirth" --wallet-dir ./wallet

Executes the OID4VP direct_post flow:

  1. Loads the specified credential from the wallet
  2. Fetches the authorization request object from the request URI
  3. Builds a selective disclosure presentation with only the specified claims
  4. Signs a KB-JWT (Key Binding JWT) with the holder key, binding nonce and audience
  5. Submits the vp_token via direct_post to the verifier's response URI
Option Required Default Description
--request-uri Yes - OpenID4VP Authorization Request URI
--credential Yes - Credential type to present (e.g., VerifiedIdentityCredential)
--disclose Yes - Comma-separated claim names to disclose
--wallet-dir No ./wallet Directory for keys and credentials

Exit Codes (HAIP commands)

Code Meaning
0 Success
1 General error (invalid URI, missing credential, unexpected failure)
2 Authentication error (token exchange failed, request object fetch failed)
3 Credential/presentation rejected by server
4 Network or metadata error

Wallet Directory Structure

The HAIP commands use a flat file-based wallet:

wallet/
├── holder-key.pem               # ES256 (P-256) private key — auto-generated on first use
├── holder-key.jwk.json           # Public JWK for reference
└── credentials/
    ├── VerifiedIdentityCredential.sdjwt
    └── DrivingLicenceCredential.sdjwt

Holder Key

The holder key is an ECDSA P-256 (ES256) key pair used for:

  • JWT proof of possession during credential issuance (binds the credential to this key via cnf)
  • KB-JWT signing during credential presentation (proves the presenter holds the key)

The key is generated on first use and persisted as a PEM file. Subsequent receive and present invocations reuse the same key. Both walkthroughs in walkthroughs/HaipIdentityAttestation/ and walkthroughs/HaipDrivingLicence/ share the same wallet directory and holder key.

Important Notes

  • IssuerUrl resolution: The issuer URL embedded in the credential offer must be host-resolvable (typically http://127.0.0.1 when running against Docker). The agent runs on the host machine and must reach the issuer's metadata, token, and credential endpoints directly.
  • Issuer JWK in header: In dev/walkthrough mode, the issuer's public JWK is embedded in the JWS header. Production deployments use x5c certificate chains.
  • No authentication required for HAIP commands: Unlike the run and validate commands, the HAIP commands do not authenticate against Sorcha. They interact directly with the OID4VCI/OID4VP endpoints using the pre-authorized code or presentation request URI.

Decision Engines

Rules Engine (JSON Logic)

Deterministic rule evaluation using JSON Logic syntax. Rules are evaluated top-to-bottom; first match wins.

{
  "mode": "rules",
  "rules": [
    {
      "actionName": "Cost Approval",
      "condition": { ">": [{ "var": "payload.cost" }, 500000] },
      "decision": "reject",
      "payload": { "reason": "Exceeds budget threshold" }
    },
    {
      "actionName": "Cost Approval",
      "condition": { "==": [true, true] },
      "decision": "approve",
      "payload": { "approved": true }
    }
  ]
}

AI Engine (Claude)

LLM-powered decisions using a persona prompt and action context:

{
  "mode": "ai",
  "ai": {
    "provider": "anthropic",
    "model": "claude-sonnet-4-6",
    "temperature": 0.3,
    "personaFile": "./persona.md",
    "apiKeyEnvVar": "ANTHROPIC_API_KEY"
  }
}

Variable Resolution

  • $env:VAR_NAME — Resolved from environment variables (recommended for secrets)
  • {{placeholder}} — Resolved from a state.json file (useful for dynamic IDs from setup scripts)

Pre-Actions

Hooks that execute before payload submission, e.g. file uploads:

{
  "preActions": [
    {
      "type": "file-upload",
      "config": {
        "fieldName": "document",
        "filePath": "./report.pdf",
        "fileName": "report.pdf",
        "contentType": "application/pdf"
      }
    }
  ]
}

Features

  • Dual Inbox Discovery — Real-time SignalR + configurable HTTP polling with automatic deduplication
  • Pluggable Decision Engines — Rules (JSON Logic) or AI (Claude) with schema validation
  • File Upload Pre-Actions — Chunked encrypted file submission (up to 40MB)
  • Resilient Execution — Polly retry/circuit-breaker, SignalR auto-reconnect, JWT auto-refresh
  • Audit Logging — JSONL append-only trail of all decisions and submissions
  • Persona Mode — Optional autonomous initiator loop alongside reactive inbox (Feature 110)
  • Cross-Platform — Runs on Windows, macOS, and Linux

Persona Mode

A persona is an optional JSON file that lets an agent initiate a workflow instead of only reacting to its inbox. Enabled by adding a personaFile field to the actor definition:

{
  "actor": { "name": "procurement-mgr", ... },
  "personaFile": "../personas/procurement-mgr-kickoff.persona.json",
  "mode": "rules",
  "rules": [ ... ]
}

The persona file declares a trigger (once in v1), a target (blueprint + instance + action index), and a payload template with substitution tokens (${now}, ${uuid}, ${counter}, ${random.int|decimal|choice}). The persona loop runs alongside the reactive inbox loop using the same wallet, auth, and HTTP client — agents without personaFile are unaffected.

Typical use is unblocking multi-agent walkthroughs that would otherwise hang because the first action has no prior transaction to populate any agent's inbox. See specs/110-agent-persona-mode/quickstart.md for the full guide.

Exit Codes

Code Meaning
0 Success
1 General error
2 Authentication error
4 Validation error
6 Configuration error
7 Network error
8 Service error

Requirements

  • .NET 10 runtime
  • Access to a running Sorcha platform instance
  • Valid user credentials with wallet access

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
2.21.1 36 7/20/2026
2.20.1 103 7/10/2026
2.19.1 94 7/7/2026
2.18.1 97 7/7/2026
2.17.1 102 7/3/2026
2.16.1 107 6/29/2026
2.15.1 119 6/4/2026
1.0.1 126 4/7/2026