Skip to content

Configuration

Configuration is read from .simple-ots/config.toml in the current directory (or from --config PATH).

The file is TOML format. All fields are optional — if the file doesn't exist, defaults are used.


Fields

dids

Type: []string
Default: [] (empty)

A list of DID strings to bind to each file's leaf hashes. Each DID produces a separate leaf per file per path variant. This is the core mechanism for selective disclosure of identity: you can reveal a file proof tied to one DID without disclosing that the same file is also tied to another identity.

toml
dids = ["did:web:alice.example.com", "did:web:bob.example.com"]

DIDs are arbitrary strings — any string that is unique and meaningful to you works. The did:web:, did:key:, and did:ion: methods are common choices, but there is no validation beyond being a non-empty string.


path_variants

Type: []string
Default: ["null", "filename", "relative"]
Valid values: "null", "filename", "relative"

Controls which representations of the file path are included in each leaf. Each variant produces a separate leaf, enabling selective disclosure of path information.

Valuepath field in leafUse case
"null"nullProve file content and DID without revealing its location
"filename""main.go"Reveal the filename but not the directory structure
"relative""src/main.go"Reveal the full relative path from the project root
toml
path_variants = ["null", "filename", "relative"]

include_no_did

Type: bool
Default: true

When true, an additional leaf is generated for each file with did = null, regardless of the dids list. This enables proving that a file existed without revealing any identity.

toml
include_no_did = true

Setting this to false requires at least one DID in dids; otherwise no leaves would be generated for any file.


Leaf count formula

leaves_per_file = len(path_variants) × (len(dids) + (include_no_did ? 1 : 0))
total_leaves    = files × leaves_per_file

Example: 500 files, 2 DIDs, 3 path variants, include_no_did = true:

leaves_per_file = 3 × (2 + 1) = 9
total_leaves    = 500 × 9     = 4500

4500 SHA-256 hashes = ~144 KB of leaf data. Merkle tree depth ≈ 13 levels. OTS anchor = 1 root hash (32 bytes). Negligible overhead.


Canonical JSON structure

The leaf hash is SHA-256(canonical_JSON) where canonical JSON is produced by marshalling a map[string]interface{} with Go's encoding/json, which sorts keys lexicographically. The resulting JSON always has this shape:

json
{
  "content_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  "datetime": "2026-06-26T12:00:00Z",
  "did": "did:web:example.com",
  "path": "src/main.go"
}
  • content_sha256 — hex SHA-256 of raw file bytes
  • datetime — file mtime in RFC 3339 UTC (time.RFC3339, second precision)
  • did — DID string or JSON null
  • path — path string or JSON null

Keys are always in alphabetical order (content_sha256, datetime, did, path). This makes the hash fully reproducible on any platform with any JSON library, as long as null values are included (not omitted).


Config file location

SituationConfig loaded from
Default<cwd>/.simple-ots/config.toml
--config PATHExact path given
File missingBuilt-in defaults (no error)

Full example

toml
# .simple-ots/config.toml

# Bind hashes to these identities
dids = [
  "did:web:alice.example.com",
  "did:web:bob.example.com",
]

# Path representations to generate per file
path_variants = ["null", "filename", "relative"]

# Always include a leaf with no DID (for anonymous proofs)
include_no_did = true

See Config Examples for more patterns.

Released under the Apache License 2.0.