This page documents all available Sentinel CLI subcommands and their usage patterns.
Initialize a Store
Creates a new Sentinel store at the specified path with the necessary directory structure and metadata.
Usage:
sentinel init --path <PATH> [OPTIONS]Required Arguments:
-p, --path <PATH>: Path to the store directory
Optional Arguments:
--passphrase <PASSPHRASE>: Passphrase for encrypting the signing key--signing-key <KEY>: Hex-encoded signing key to use. If not provided, a new one is generated if initializing a new store
Examples:
# Initialize a new store
sentinel init --path /data/my-store
# Initialize with a specific signing key
sentinel init --path /data/my-store --signing-key 1234abcd...
# Initialize with passphrase protection
sentinel init --path /data/my-store --passphrase "my-secure-passphrase"
# Combine all options
sentinel init --path /data/my-store \
--passphrase "my-secure-passphrase" \
--signing-key 1234abcd... \
--encryption-algorithm aes256gcmsivWhat It Does:
- Creates the store directory if it doesn’t exist
- Initializes metadata files
- Generates or imports a signing key
- Optionally encrypts the signing key with the provided passphrase
- Sets up the internal
.keyscollection for key storage (if applicable)
Generate Cryptographic Keys
Generates cryptographic keys and other artifacts for use with Sentinel.
Tip: The
generatecommand can be abbreviated asgen.
Generate a Cryptographic Key
Generates a new cryptographic key of the specified type and outputs it as a hex string.
Usage:
sentinel generate key <KEY_TYPE>
sentinel gen key <KEY_TYPE>Key Types:
signingGenerate an Ed25519 signing key pairencryptionGenerate a 256-bit encryption key
Examples:
# Generate a signing key
sentinel generate key signing
# Output: 1a2b3c4d5e6f...
# Generate an encryption key
sentinel gen key encryption
# Output: 9f8e7d6c5b4a...
# Save to a file
sentinel gen key signing > signing-key.txt
# Use with init command
SIGNING_KEY=$(sentinel gen key signing)
sentinel init --path /data/my-store --signing-key $SIGNING_KEYCreate a Collection
Creates a new collection within an existing store. Refer to the Collection API for more details.
Usage:
sentinel create-collection --store <STORE_PATH> --name <COLLECTION_NAME>Required Arguments:
-s, --store <STORE_PATH>- Path to the store directory-n, --name <COLLECTION_NAME>- Name of the collection to create
Examples:
# Create a users collection
sentinel create-collection --store /data/my-store --name users
# Create an audit logs collection
sentinel create-collection --store /data/my-store --name audit_logs
# Create with custom encryption
sentinel create-collection \
--store /data/my-store \
--name sensitive-data \
--encryption-algorithm aes256gcmsivWhat It Does:
- Creates a subdirectory within the store for the collection
- Initializes collection metadata (
.metadata.json) - Sets up subdirectories for indices, deleted documents, and WAL
Insert a Document
Inserts a new document into a collection. The document must be valid JSON.
Usage:
sentinel insert --store <STORE_PATH> --collection <COLLECTION_NAME> --id <DOCUMENT_ID> --data <JSON_DATA>Required Arguments:
-s, --store <STORE_PATH>: Path to the store directory-c, --collection <COLLECTION_NAME>: Name of the collection-i, --id <DOCUMENT_ID>: Unique identifier for the document-d, --data <JSON_DATA>: JSON data for the document
Examples:
# Insert a simple document
sentinel insert \
--store /data/my-store \
--collection users \
--id user-123 \
--data '{"name": "Alice", "email": "[email protected]"}'
# Insert from a file
sentinel insert \
--store /data/my-store \
--collection users \
--id user-456 \
--data "$(cat user.json)"
# Insert with verbose logging
sentinel insert -v \
--store /data/my-store \
--collection audit_logs \
--id audit-2026-01-15 \
--data '{"action": "login", "user": "bob", "timestamp": "2026-01-15T10:30:00Z"}'What It Does:
- Validates the JSON data
- Adds metadata fields (
id,version,created_at,hash,signature) - Writes the document to disk as
<collection>/<id>.json - Updates indices
- Logs the operation to the WAL
Retrieve a Document
Retrieves a document from a collection and prints it to stdout.
Usage:
sentinel get --store <STORE_PATH> --collection <COLLECTION_NAME> --id <DOCUMENT_ID>Required Arguments:
-s, --store <STORE_PATH>: Path to the store directory-c, --collection <COLLECTION_NAME>: Name of the collection-i, --id <DOCUMENT_ID>: Document identifier
Examples:
# Get a document
sentinel get \
--store /data/my-store \
--collection users \
--id user-123
# Save to a file
sentinel get \
--store /data/my-store \
--collection users \
--id user-123 > user-123.json
# Pretty-print with jq
sentinel get \
--store /data/my-store \
--collection users \
--id user-123 | jq .What It Does:
- Reads the document file from disk
- Verifies the document hash for integrity
- Optionally verifies the signature
- Prints the document JSON to stdout
Update a Document
Updates an existing document in a collection. The entire document is replaced with the new data.
Usage:
sentinel update --store <STORE_PATH> --collection <COLLECTION_NAME> --id <DOCUMENT_ID> --data <JSON_DATA>Required Arguments:
-s, --store <STORE_PATH>: Path to the store directory-c, --collection <COLLECTION_NAME>: Name of the collection-i, --id <DOCUMENT_ID>: Document identifier-d, --data <JSON_DATA>: New JSON data for the document
Examples:
# Update a document
sentinel update \
--store /data/my-store \
--collection users \
--id user-123 \
--data '{"name": "Alice Smith", "email": "[email protected]"}'
# Update from a file
sentinel update \
--store /data/my-store \
--collection users \
--id user-123 \
--data "$(cat updated-user.json)"
# Incremental update with jq
CURRENT=$(sentinel get --store /data/my-store --collection users --id user-123)
UPDATED=$(echo "$CURRENT" | jq '.email = "[email protected]"')
sentinel update \
--store /data/my-store \
--collection users \
--id user-123 \
--data "$UPDATED"What It Does:
- Validates the new JSON data
- Updates metadata (
version,updated_at,hash,signature) - Replaces the document file on disk
- Updates indices
- Logs the operation to the WAL
List Documents
Lists all document IDs in a collection.
Usage:
sentinel list --store <STORE_PATH> --collection <COLLECTION_NAME>Required Arguments:
-s, --store <STORE_PATH>: Path to the store directory-c, --collection <COLLECTION_NAME>: Name of the collection
Examples:
# List all users
sentinel list --store /data/my-store --collection users
# Count documents with wc
sentinel list --store /data/my-store --collection users | wc -l
# Use with xargs to process each document
sentinel list --store /data/my-store --collection users | \
xargs -I {} sentinel get --store /data/my-store --collection users --id {}What It Does:
- Reads the collection directory
- Lists all
.jsonfiles (excluding hidden files and subdirectories) - Prints document IDs (filenames without
.jsonextension) to stdout
Query Documents
Query documents in a collection with powerful filtering, sorting, pagination, and field projection.
Usage:
sentinel query \
--store <STORE_PATH> \
--collection <COLLECTION_NAME> \
[--filter <FILTER>...] \
[--sort <FIELD:ORDER>] \
[--limit <N>] \
[--offset <N>] \
[--project <FIELDS>] \
[--format <FORMAT>]Required Arguments:
-s, --store <STORE_PATH>: Path to the store directory-c, --collection <COLLECTION_NAME>: Name of the collection
Optional Arguments:
--filter <FILTER>: Filter expression (can be used multiple times for AND logic)--sort <FIELD:ORDER>: Sort by field (e.g.,name:ascorage:desc)--limit <N>: Maximum number of results to return--offset <N>: Number of results to skip (for pagination)--project <FIELDS>: Comma-separated list of fields to include in results--format <FORMAT>: Output format (jsonortable, default:json)--passphrase <PASSPHRASE>: Passphrase for decrypting the signing key
Filter Syntax
Filters use the following syntax patterns:
| Operator | Syntax | Example | Description |
|---|---|---|---|
| Equals | field=value | role=admin | Exact match |
| Greater Than | field>value | age>25 | Numeric comparison |
| Less Than | field<value | score<100 | Numeric comparison |
| Greater or Equal | field>=value | salary>=50000 | Numeric comparison |
| Less or Equal | field<=value | experience<=10 | Numeric comparison |
| Contains | field~substring | name~John | String contains |
| Starts With | field^prefix | email^admin@ | String starts with |
| Ends With | field$suffix | domain$.com | String ends with |
| In | field in:val1,val2 | status in:active,pending | Value in list |
| Exists | field exists:true/false | phone exists:true | Field exists |
Examples:
# Find all active admins
sentinel query \
--store /data/my-store \
--collection users \
--filter "role=admin" \
--filter "status=active"
# Find users over 25 in Engineering department
sentinel query \
--store /data/my-store \
--collection users \
--filter "age>25" \
--filter "department=Engineering"
# Search for emails containing "example"
sentinel query \
--store /data/my-store \
--collection users \
--filter "email~example"
# Find users with phone numbers
sentinel query \
--store /data/my-store \
--collection users \
--filter "phone exists:true"
# Complex query with sorting and pagination
sentinel query \
--store /data/my-store \
--collection users \
--filter "age>=21" \
--filter "department in:Engineering,Sales" \
--sort "name:asc" \
--limit 10 \
--offset 0 \
--project "name,email,department"
# Get recent audit logs
sentinel query \
--store /data/my-store \
--collection audit_logs \
--sort "created_at:desc" \
--limit 100
# Table format output for readability
sentinel query \
--store /data/my-store \
--collection users \
--filter "role=admin" \
--format table
# JSON output for scripting
sentinel query \
--store /data/my-store \
--collection users \
--filter "age>30" \
--format json | jq '.[] | {name: .data.name, age: .data.age}'What It Does:
- Parses all filter expressions
- Scans the collection directory and reads matching documents
- Applies filters in memory (AND logic for multiple filters)
- Sorts results if
--sortis specified - Applies pagination (
--offsetand--limit) - Projects fields if
--projectis specified - Outputs results in the specified format
- Reports query execution time and count
Output Format:
JSON format (default):
[
{
"id": "user-123",
"version": 1,
"created_at": "2026-01-17T10:00:00Z",
"updated_at": "2026-01-17T10:00:00Z",
"hash": "a1b2c3...",
"signature": "d4e5f6...",
"data": {
"name": "Alice",
"email": "[email protected]"
}
}
]Table format (for human readability):
┌──────────┬───────┬──────────────────────┐
│ ID │ Name │ Email │
├──────────┼───────┼──────────────────────┤
│ user-123 │ Alice │ [email protected] │
│ user-456 │ Bob │ [email protected] │
└──────────┴───────┴──────────────────────┘
Query executed in 5.23ms
Total results: 2Delete a Document
Deletes a document from a collection (soft delete by default).
Usage:
sentinel delete --store <STORE_PATH> --collection <COLLECTION_NAME> --id <DOCUMENT_ID>Required Arguments:
-s, --store <STORE_PATH>: Path to the store directory-c, --collection <COLLECTION_NAME>: Name of the collection-i, --id <DOCUMENT_ID>: Document identifier
Examples:
# Delete a document
sentinel delete \
--store /data/my-store \
--collection users \
--id user-123
# Delete with verbose logging
sentinel delete -v \
--store /data/my-store \
--collection audit_logs \
--id audit-2025-12-31What It Does:
- Moves the document to the
.deleted/subdirectory (soft delete) - Updates indices
- Logs the operation to the WAL
- The document can still be accessed for audit purposes
Note: Sentinel uses soft deletes by default for audit compliance. The document is moved to a .deleted/ directory within the collection but remains accessible.
Complete Workflow Examples
Setting Up a New Store
# Generate keys
SIGNING_KEY=$(sentinel gen key signing)
ENCRYPTION_KEY=$(sentinel gen key encryption)
# Initialize the store
sentinel init \
--path /data/my-store \
--signing-key $SIGNING_KEY \
--passphrase "my-secure-passphrase" \
--encryption-algorithm xchacha20poly1305
# Create collections
sentinel create-collection --store /data/my-store --name users
sentinel create-collection --store /data/my-store --name audit_logs
sentinel create-collection --store /data/my-store --name certificatesManaging Documents
# Insert documents
sentinel insert \
--store /data/my-store \
--collection users \
--id user-001 \
--data '{"name": "Alice", "role": "admin"}'
sentinel insert \
--store /data/my-store \
--collection users \
--id user-002 \
--data '{"name": "Bob", "role": "user"}'
# Retrieve and modify
USER=$(sentinel get --store /data/my-store --collection users --id user-001)
MODIFIED=$(echo "$USER" | jq '.role = "superadmin"')
sentinel update \
--store /data/my-store \
--collection users \
--id user-001 \
--data "$MODIFIED"
# Delete
sentinel delete --store /data/my-store --collection users --id user-002Audit Trail Operations
# Create audit log entries
sentinel insert \
--store /data/my-store \
--collection audit_logs \
--id "$(date +%Y%m%d-%H%M%S)-login" \
--data "{\"action\": \"login\", \"user\": \"alice\", \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}"
# View all audit logs (using filesystem tools)
ls -la /data/my-store/audit_logs/
# Search audit logs with grep
grep -r "alice" /data/my-store/audit_logs/Algorithm Configuration Examples
# High-security configuration
sentinel init \
--path /data/high-security-store \
--hash-algorithm blake3 \
--signature-algorithm ed25519 \
--encryption-algorithm xchacha20poly1305 \
--key-derivation-algorithm argon2id
# Constrained environment configuration
sentinel init \
--path /data/embedded-store \
--hash-algorithm blake3 \
--signature-algorithm ed25519 \
--encryption-algorithm ascon128 \
--key-derivation-algorithm pbkdf2See Also
- CLI Reference - Global options, flags, and configuration
- Quick Start - Get started with Sentinel quickly
- Store API - Programmatic store management
- Collection API - Collection operations
- Document API - Document structure and operations