AT Protocol PLC Command-Line Tools#
Command-line tools for working with AT Protocol PLC (Public Ledger of Credentials) DIDs.
Tools#
plc-audit: DID Audit Log Validator#
Validates the cryptographic integrity of a DID's audit log from plc.directory.
Features#
- ๐ Fetch Audit Logs: Retrieves complete operation history from plc.directory
- ๐ Cryptographic Validation: Verifies all signatures using rotation keys
- ๐ Chain Verification: Validates operation chain linkage (prev references)
- ๐ Detailed Output: Shows operation history and final DID state
- โก Fast & Reliable: Built with Rust for performance and safety
Usage#
# Basic validation
cargo run --bin plc-audit --features cli -- did:plc:z72i7hdynmk6r22z27h6tvur
# Verbose mode (show all operations)
cargo run --bin plc-audit --features cli -- did:plc:z72i7hdynmk6r22z27h6tvur --verbose
# Quiet mode (VALID/INVALID only)
cargo run --bin plc-audit --features cli -- did:plc:z72i7hdynmk6r22z27h6tvur --quiet
# Custom PLC directory
cargo run --bin plc-audit --features cli -- did:plc:example --plc-url https://custom.plc.directory
plc-fork-viz: Fork Visualizer#
Visualizes forks in a DID's operation chain, showing which operations won/lost based on rotation key priority and the 72-hour recovery window.
Features#
- ๐ Fork Detection: Identifies competing operations in the chain
- ๐ Priority Analysis: Determines which rotation key signed each operation
- โฑ๏ธ Recovery Window: Applies 72-hour recovery window rules
- ๐ Multiple Formats: Tree, JSON, and Markdown visualization
- ๐จ Color Coding: Green for canonical operations, red for rejected
Usage#
# Basic fork visualization
cargo run --bin plc-fork-viz --features cli -- did:plc:ewvi7nxzyoun6zhxrhs64oiz
# Verbose mode (detailed operation info)
cargo run --bin plc-fork-viz --features cli -- did:plc:ewvi7nxzyoun6zhxrhs64oiz --verbose
# Show timestamps and recovery window calculations
cargo run --bin plc-fork-viz --features cli -- did:plc:ewvi7nxzyoun6zhxrhs64oiz --timing
# Show full DIDs/CIDs
cargo run --bin plc-fork-viz --features cli -- did:plc:ewvi7nxzyoun6zhxrhs64oiz --full-ids
# Output as JSON
cargo run --bin plc-fork-viz --features cli -- did:plc:ewvi7nxzyoun6zhxrhs64oiz --format json
# Output as Markdown
cargo run --bin plc-fork-viz --features cli -- did:plc:ewvi7nxzyoun6zhxrhs64oiz --format markdown
Output Formats#
Tree Format (default):
Fork at operation referencing bafyre...abc123
โโ ๐ด โ CID: bafyre...def456
โ Signed by: rotation_key[1]
โ Reason: Invalidated by higher-priority key[0] within recovery window
โโ ๐ข โ CID: bafyre...ghi789
Signed by: rotation_key[0]
Status: CANONICAL (winner)
JSON Format:
[
{
"prev_cid": "bafyre...",
"winner_cid": "bafyre...",
"operations": [...]
}
]
Markdown Format:
| Status | CID | Key Index | Timestamp | Reason |
|---|---|---|---|---|
| โ Winner | bafyre...ghi789 | 0 | 2025-01-15 14:30:00 | Canonical operation |
| โ Rejected | bafyre...def456 | 1 | 2025-01-15 10:00:00 | Invalidated by higher-priority key[0] |
Fork Resolution Rules#
- Rotation Key Priority: Keys are ordered by array index (0 = highest priority)
- Recovery Window: 72 hours from the first operation's timestamp
- First-Received Default: The operation received first wins unless invalidated
- Higher Priority Override: A higher-priority key can invalidate if:
- It arrives within 72 hours
- Its key index is lower (e.g., key[0] beats key[1])
Example: No Forks#
$ cargo run --bin plc-fork-viz --features cli -- did:plc:ewvi7nxzyoun6zhxrhs64oiz
๐ Analyzing forks in: did:plc:ewvi7nxzyoun6zhxrhs64oiz
Source: https://plc.directory
๐ Audit log contains 5 operations
โ
No forks detected - this is a linear operation chain
All operations form a single canonical path from genesis to tip.
Example: Fork Detected#
$ cargo run --bin plc-fork-viz --features cli -- did:plc:z7x2k3j4m5n6 --timing
๐ Analyzing forks in: did:plc:z7x2k3j4m5n6
Source: https://plc.directory
๐ Audit log contains 8 operations
โ ๏ธ Detected 1 fork point(s)
๐ Fork Visualization (Tree Format)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Fork at operation referencing bafyre...abc123
โโ ๐ด โ CID: bafyre...def456
โ Signed by: rotation_key[1]
โ Timestamp: 2025-01-15 10:00:00 UTC
โ Reason: Invalidated by higher-priority key[0] within recovery window
โ
โโ ๐ข โ CID: bafyre...ghi789
โ Signed by: rotation_key[0]
โ Timestamp: 2025-01-15 14:00:00 UTC
โ Status: CANONICAL (winner)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Summary:
Total operations: 8
Fork points: 1
Rejected operations: 1
๐ Fork Resolution Details:
Fork 1: Winner is bafyre...ghi789 (signed by key[0])
Building & Installation#
Build Both Tools#
cargo build --bins --features cli --release
Install to ~/.cargo/bin#
cargo install --path . --features cli
Then use directly:
plc-audit did:plc:ewvi7nxzyoun6zhxrhs64oiz
plc-fork-viz did:plc:ewvi7nxzyoun6zhxrhs64oiz
Common Workflows#
Workflow 1: Validate and Check for Forks#
# First validate the audit log
$ plc-audit did:plc:ewvi7nxzyoun6zhxrhs64oiz
โ
Validation successful!
# Then check for forks
$ plc-fork-viz did:plc:ewvi7nxzyoun6zhxrhs64oiz
Workflow 2: Export Fork Data#
# Export as JSON for analysis
$ plc-fork-viz did:plc:ewvi7nxzyoun6zhxrhs64oiz --format json > forks.json
# Generate Markdown report
$ plc-fork-viz did:plc:ewvi7nxzyoun6zhxrhs64oiz --format markdown > FORK_REPORT.md
Workflow 3: Monitor DIDs#
#!/bin/bash
# Monitor a DID for changes and forks
DID="did:plc:ewvi7nxzyoun6zhxrhs64oiz"
# Validate
if plc-audit $DID --quiet; then
echo "โ
DID is valid"
# Check for forks
plc-fork-viz $DID --format json > /tmp/forks.json
if [ -s /tmp/forks.json ]; then
echo "โ ๏ธ Forks detected!"
plc-fork-viz $DID
fi
else
echo "โ DID validation failed!"
exit 1
fi
Understanding Fork Visualization#
Symbols#
- ๐ฑ Genesis operation (creates the DID)
- ๐ข โ Canonical operation (winner)
- ๐ด โ Rejected operation (lost the fork)
- โโ Fork branch (more operations follow)
- โโ Final fork branch
Rejection Reasons#
-
"Invalidated by higher-priority key[N] within recovery window"
- A higher-priority rotation key signed a competing operation within 72 hours
-
"Higher-priority key[N] but outside 72-hour recovery window (X hours late)"
- A higher-priority key tried to invalidate but arrived too late
-
"Lower-priority key[N] (current winner has key[M])"
- This operation was signed by a lower-priority key and can't override
Troubleshooting#
Error: "Invalid DID format"#
DID must follow format: did:plc:<24 lowercase base32 characters>
Error: "Failed to fetch audit log"#
- Check internet connection
- Verify DID exists on plc.directory
- Try
--plc-urlfor custom PLC directories
No forks detected but expected#
- The DID may have a linear operation chain
- All operations were submitted sequentially without conflicts
Technical Details#
plc-audit validates:
- DID format (prefix, length, base32 encoding)
- Chain linkage (prev references)
- Cryptographic signatures (ECDSA with P-256/secp256k1)
- State consistency
plc-fork-viz implements:
- Fork detection (multiple operations with same prev CID)
- Rotation key index resolution
- Priority-based fork resolution
- 72-hour recovery window enforcement
Both tools use:
reqwestfor HTTP requestsatproto-plclibrary for cryptographic operationsclapfor command-line parsing
See Also#
- AT Protocol PLC Specification
- Fork Resolution Implementation Report
- Implementation Summary
- Library Documentation
License#
Dual-licensed under MIT or Apache-2.0, same as the parent library.