Configuration Reference

This is the comprehensive configuration guide covering zero-config quickstart, storage backends, observability, and environment variables. For the raw schema field list, see Config File Schema.

Overview

Key resolution for verifiers

When verifying signed documents, JACS resolves the signer’s public key using a configurable order of sources. Set JACS_KEY_RESOLUTION (environment variable or in config) to a comma-separated list of sources: local (local key cache by publicKeyHash), dns (DNS TXT fingerprint validation), hai (HAI key service). Example: JACS_KEY_RESOLUTION=local,hai or local,dns,hai. The first source that yields verifiable key material is used. Use verify_standalone() with explicit keyResolution for one-off verification without loading a full config.

Zero-Config Path

If you just want to sign and verify without manual config setup, use quickstart(name, domain, ...):

import jacs.simple as jacs
info = jacs.quickstart(name="config-agent", domain="config.example.com")
print(info.config_path, info.public_key_path, info.private_key_path)
const jacs = require('@hai.ai/jacs/simple');
const info = await jacs.quickstart({
  name: 'config-agent',
  domain: 'config.example.com',
});
console.log(info.configPath, info.publicKeyPath, info.privateKeyPath);
jacs quickstart --name config-agent --domain config.example.com

quickstart(name, domain, ...) creates a persistent agent with keys on disk (default algorithm: pq2025). If ./jacs.config.json already exists, it loads it; otherwise it creates a new agent. Returned AgentInfo includes config/key paths (config_path/public_key_path/private_key_path in Python, configPath/publicKeyPath/privateKeyPath in Node) plus key directory metadata so you can locate key material immediately. Rust/CLI quickstart requires an explicit password source (JACS_PRIVATE_KEY_PASSWORD, or JACS_PASSWORD_FILE in CLI). Python/Node can auto-generate a password if needed; set JACS_SAVE_PASSWORD_FILE=true if you want that generated password persisted to ./jacs_keys/.jacs_password.

Minimal Configuration

For persistent agents, a config file needs only two fields (plus $schema):

{
  "$schema": "https://hai.ai/schemas/jacs.config.schema.json",
  "jacs_agent_id_and_version": "YOUR_AGENT_ID:YOUR_VERSION",
  "jacs_agent_key_algorithm": "pq2025"
}

All other settings use sensible defaults (./jacs_data, ./jacs_keys, fs storage). Override only what you need.

Complete Example Configuration

{
  "$schema": "https://hai.ai/schemas/jacs.config.schema.json",
  "jacs_use_security": "false",
  "jacs_data_directory": "./jacs_data",
  "jacs_key_directory": "./jacs_keys",
  "jacs_agent_private_key_filename": "jacs.private.pem.enc",
  "jacs_agent_public_key_filename": "jacs.public.pem",
  "jacs_agent_key_algorithm": "pq2025",
  "jacs_default_storage": "fs",
  "observability": {
    "logs": {
      "enabled": true,
      "level": "info",
      "destination": {
        "type": "file",
        "path": "./logs"
      },
      "headers": {
        "Authorization": "Bearer token",
        "X-API-Key": "secret"
      }
    },
    "metrics": {
      "enabled": true,
      "destination": {
        "type": "prometheus",
        "endpoint": "http://localhost:9090/api/v1/write",
        "headers": {
          "Authorization": "Basic dXNlcjpwYXNz"
        }
      },
      "export_interval_seconds": 60,
      "headers": {
        "X-Service": "jacs"
      }
    },
    "tracing": {
      "enabled": true,
      "sampling": {
        "ratio": 0.1,
        "parent_based": true,
        "rate_limit": 100
      },
      "resource": {
        "service_name": "jacs",
        "service_version": "0.4.0",
        "environment": "production",
        "attributes": {
          "team": "platform",
          "region": "us-west-2"
        }
      }
    }
  }
}

Observability Configuration

JACS supports comprehensive observability through configurable logging, metrics, and tracing. All observability features are optional and can be configured in the jacs.config.json file.

Logs Configuration

Controls how JACS generates and outputs log messages.

FieldTypeRequiredDescription
enabledbooleanYesWhether logging is enabled
levelstringYesMinimum log level: trace, debug, info, warn, error
destinationobjectYesWhere logs are sent (see destinations below)
headersobjectNoAdditional headers for remote destinations

Log Destinations

File Logging

{
  "type": "file",
  "path": "./logs"
}

Writes logs to rotating files in the specified directory.

Console Logging (stderr)

{
  "type": "stderr"
}

Outputs logs to standard error stream.

OpenTelemetry Protocol (OTLP)

{
  "type": "otlp",
  "endpoint": "http://localhost:4317",
  "headers": {
    "Authorization": "Bearer token"
  }
}

Sends logs to an OTLP-compatible endpoint (like Jaeger, Grafana Cloud).

Null (disabled)

{
  "type": "null"
}

Discards all log output.

Metrics Configuration

Controls collection and export of application metrics.

FieldTypeRequiredDescription
enabledbooleanYesWhether metrics collection is enabled
destinationobjectYesWhere metrics are exported (see destinations below)
export_interval_secondsintegerNoHow often to export metrics (default: 60)
headersobjectNoAdditional headers for remote destinations

Metrics Destinations

Prometheus Remote Write

{
  "type": "prometheus",
  "endpoint": "http://localhost:9090/api/v1/write",
  "headers": {
    "Authorization": "Basic dXNlcjpwYXNz"
  }
}

Exports metrics in Prometheus format to a remote write endpoint.

OpenTelemetry Protocol (OTLP)

{
  "type": "otlp",
  "endpoint": "http://localhost:4317",
  "headers": {
    "Authorization": "Bearer token"
  }
}

Exports metrics to an OTLP-compatible endpoint.

File Export

{
  "type": "file",
  "path": "./metrics.txt"
}

Writes metrics to a local file.

Console Output (stdout)

{
  "type": "stdout"
}

Prints metrics to standard output.

Tracing Configuration

Controls distributed tracing for request flows.

FieldTypeRequiredDescription
enabledbooleanYesWhether tracing is enabled
samplingobjectNoSampling configuration (see below)
resourceobjectNoService identification (see below)

Sampling Configuration

Controls which traces are collected to manage overhead.

FieldTypeDefaultDescription
rationumber1.0Fraction of traces to sample (0.0-1.0)
parent_basedbooleantrueWhether to respect parent trace sampling decisions
rate_limitintegernoneMaximum traces per second

Examples:

  • "ratio": 1.0 - Sample all traces (100%)
  • "ratio": 0.1 - Sample 10% of traces
  • "ratio": 0.01 - Sample 1% of traces
  • "rate_limit": 10 - Maximum 10 traces per second

Resource Configuration

Identifies the service in distributed tracing systems.

FieldTypeRequiredDescription
service_namestringYesName of the service
service_versionstringNoVersion of the service
environmentstringNoEnvironment (dev, staging, prod)
attributesobjectNoCustom key-value attributes

Authentication & Headers

For remote destinations (OTLP, Prometheus), you can specify authentication headers:

Bearer Token Authentication:

"headers": {
  "Authorization": "Bearer your-token-here"
}

Basic Authentication:

"headers": {
  "Authorization": "Basic dXNlcjpwYXNz"
}

API Key Authentication:

"headers": {
  "X-API-Key": "your-api-key",
  "X-Auth-Token": "your-auth-token"
}

Common Patterns

Development Configuration

"observability": {
  "logs": {
    "enabled": true,
    "level": "debug",
    "destination": { "type": "stderr" }
  },
  "metrics": {
    "enabled": true,
    "destination": { "type": "stdout" }
  }
}

Production Configuration

"observability": {
  "logs": {
    "enabled": true,
    "level": "info",
    "destination": {
      "type": "otlp",
      "endpoint": "https://logs.example.com:4317",
      "headers": {
        "Authorization": "Bearer prod-token"
      }
    }
  },
  "metrics": {
    "enabled": true,
    "destination": {
      "type": "prometheus",
      "endpoint": "https://metrics.example.com/api/v1/write"
    },
    "export_interval_seconds": 30
  },
  "tracing": {
    "enabled": true,
    "sampling": {
      "ratio": 0.05,
      "rate_limit": 100
    },
    "resource": {
      "service_name": "jacs",
      "service_version": "0.4.0",
      "environment": "production"
    }
  }
}

File-based Configuration

"observability": {
  "logs": {
    "enabled": true,
    "level": "info",
    "destination": {
      "type": "file",
      "path": "/var/log/jacs"
    }
  },
  "metrics": {
    "enabled": true,
    "destination": {
      "type": "file",
      "path": "/var/log/jacs/metrics.txt"
    },
    "export_interval_seconds": 60
  }
}

Environment Variable Integration

The observability configuration works alongside JACS's core configuration system.

Required Environment Variable

Only one environment variable is truly required:

  • JACS_PRIVATE_KEY_PASSWORD - Password for encrypting/decrypting private keys (required for cryptographic operations)

Configuration-Based Settings

All other JACS settings are configuration file fields that have sensible defaults:

  • jacs_data_directory - Where agent/document data is stored (default: ./jacs_data)
  • jacs_key_directory - Where cryptographic keys are stored (default: ./jacs_keys)
  • jacs_agent_key_algorithm - Cryptographic algorithm to use (default: pq2025)
  • jacs_default_storage - Storage backend (default: fs)
  • jacs_use_security / JACS_ENABLE_FILESYSTEM_QUARANTINE - Enable filesystem quarantine of executable files (default: false). The env var JACS_USE_SECURITY is deprecated; use JACS_ENABLE_FILESYSTEM_QUARANTINE instead.

These can be overridden by environment variables if needed, but they are primarily configured through the jacs.config.json file.

The observability configuration is completely optional - JACS will work without any observability configuration.

Storage Configuration

The jacs_default_storage field determines where JACS stores agent data, documents, and keys. This is a critical configuration that affects how your data is persisted and accessed.

Available Storage Backends

BackendValueDescriptionUse Case
Filesystem"fs"Signed JSON documents on local diskDefault, development, single-node deployments
Local Indexed SQLite"rusqlite"Signed documents in SQLite with FTS searchLocal search, bindings, MCP
AWS S3"aws"Amazon S3 object storageRemote object storage
Memory"memory"In-memory object storage (non-persistent)Testing, temporary data
Web Local"local"Browser local storage (WASM only)Web applications

For local indexed document search in JACS core, use "rusqlite". Additional database backends such as PostgreSQL, DuckDB, Redb, and SurrealDB live in separate crates and are not core jacs_default_storage values.

Backend-Specific Configuration

Filesystem Storage ("fs")

{
  "jacs_default_storage": "fs",
  "jacs_data_directory": "./jacs_data",
  "jacs_key_directory": "./jacs_keys"
}

Requirements: None - works out of the box Data location: Local directories as specified in config Best for: Development, local testing, single-machine deployments

Local Indexed SQLite ("rusqlite")

{
  "jacs_default_storage": "rusqlite",
  "jacs_data_directory": "./jacs_data",
  "jacs_key_directory": "./jacs_keys"
}

Requirements: Built with the default sqlite Cargo feature Database path: <jacs_data_directory>/jacs_documents.sqlite3 Best for: Local full-text search, MCP/binding document operations, single-machine deployments that want indexed reads

AWS S3 Storage ("aws")

{
  "jacs_default_storage": "aws"
}

Required Environment Variables:

  • JACS_ENABLE_AWS_BUCKET_NAME - S3 bucket name
  • AWS_ACCESS_KEY_ID - AWS access key
  • AWS_SECRET_ACCESS_KEY - AWS secret key
  • AWS_REGION - AWS region (optional, defaults to us-east-1)

Best for: Production deployments, distributed systems, cloud-native applications

Memory Storage ("memory")

{
  "jacs_default_storage": "memory"
}

Requirements: None Data persistence: None - data is lost when application stops Best for: Unit testing, temporary operations, development scenarios

Storage Behavior

  • Filesystem (fs) stores signed documents as JSON files under jacs_data/documents/.
  • Rusqlite (rusqlite) stores signed documents in jacs_data/jacs_documents.sqlite3 and is the indexed DocumentService path used by bindings and MCP.
  • Agent files and keys remain path-based assets under jacs_data/ and jacs_keys/.
  • Observability data (logs, metrics) can use separate storage via observability configuration.

DocumentService Guarantees

  • Every DocumentService read verifies the stored JACS document before returning it.
  • Every create() and update() verifies the signed document before persisting it.
  • If an update payload changes a signed JACS document without re-signing it, the write fails.
  • Visibility changes create a new signed version instead of mutating metadata in place.

Configuration Examples

Development Setup (Filesystem)

{
  "jacs_default_storage": "fs",
  "jacs_data_directory": "./dev_data",
  "jacs_key_directory": "./dev_keys"
}

Production Setup (AWS S3)

{
  "jacs_default_storage": "aws"
}

With environment variables:

export JACS_ENABLE_AWS_BUCKET_NAME="my-jacs-production-bucket"
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_REGION="us-west-2"

Security Considerations

  • AWS S3: Ensure proper IAM permissions for bucket access
  • Rusqlite: Protect the local database file with the same filesystem permissions you use for other signed artifacts
  • Filesystem: Ensure proper file system permissions for data and key directories
  • Keys: Regardless of storage backend, always set JACS_PRIVATE_KEY_PASSWORD for key encryption

Migration Between Storage Backends

When changing storage backends, you'll need to:

  1. Export existing data from the current backend
  2. Update the jacs_default_storage configuration
  3. Set any required environment variables for the new backend
  4. Import data into the new backend

JACS doesn't automatically migrate data between storage backends - this must be done manually or via custom scripts.