Q-Cap (Capability-based, encryptable content packages) is a packaging and distribution format that lets you publish data openly while keeping access cryptographically controlled by capabilities. Think: .qcap files that travel and sync like regular artifacts, but decrypt only for holders of the right capability tokens.
Status: alpha scaffold — this repository currently includes a Rust core library and CLI demo, a minimal Go registry service, and a TypeScript SDK stub. The full MVP (pack/seal/open/verify/capabilities/registry) is being built in milestones.
- Confidentiality-by-default: Envelope encryption per file with modern Authentication Encryption with Associated Data (AEAD).
- Least-privilege sharing: Capability tokens (macaroons) with caveats (expiry, paths, audience).
- Integrity & provenance: BLAKE3 Merkle tree; signed manifest.
- Portable: Single-file
.qcapartifact; easy to mirror/cdn. - Ecosystem-friendly: SDKs for TypeScript and Python; registry with S3/MinIO.
q-cap/
core/
qcap-core/ # Rust library (crypto & format building blocks)
qcap-cli/ # Rust CLI (demo cmd available today)
services/
qcap-registry/ # Go minimal registry (health check endpoint)
sdks/
ts/ # TypeScript SDK stub
api/
proto/ # Protobuf IDL (stub)
.github/workflows/ # CI
docs/ # Project docs (stubs)
flowchart LR
%% Q-Cap: Architecture at a glance
%% --- Producers / CLI ---
subgraph Producers["Producers"]
CLI["qcap-cli (Rust)\npack • seal • publish • open"]
end
%% --- Registry Service ---
subgraph Registry["qcap-registry (Go)"]
API["REST/gRPC (grpc-gateway)"]
REV["Revocations API"]
end
%% --- Storage & Indexes ---
subgraph Storage["Storage & Indexes"]
S3["S3/MinIO\n.qcap artifacts & manifests"]
PG["Postgres\nmanifest index & issuance logs"]
RED["Redis\ncache"]
end
%% --- Core Library ---
subgraph Core["qcap-core (Rust)"]
CORE["Crypto • Merkle (BLAKE3) • Capabilities (macaroons)\nAEAD: XChaCha20-Poly1305 • ed25519 • Argon2id"]
end
%% --- Consumers / SDKs ---
subgraph Consumers["Consumers (SDKs)"]
TS["TypeScript SDK (WASM)"]
PY["Python SDK (cffi)"]
end
%% --- Optional integrations ---
TLOG["Transparency Log (optional)"]
OIDC["OIDC Admin (ops)"]
%% --- Flows ---
CLI -->|publish .qcap + manifest| API
API -->|store artifacts| S3
API -->|index manifests| PG
API -->|cache hot entries| RED
API --> TLOG
OIDC -.-> API
%% Fetch paths
TS -->|fetch by id| API
PY -->|fetch by id| API
TS -->|download .qcap| S3
PY -->|download .qcap| S3
%% Open/verify using core semantics
TS -->|open • verify| CORE
PY -->|open • verify| CORE
CLI -->|open • verify| CORE
%% Revocations
REV -->|serve revocations.json| TS
REV -->|serve revocations.json| PY
%% Bindings
CORE -. WASM/FFI .- TS
CORE -. FFI .- PY
%% Styling
classDef svc fill:#eef,stroke:#446,stroke-width:1px;
classDef store fill:#efe,stroke:#474,stroke-width:1px;
classDef core fill:#fee,stroke:#844,stroke-width:1px;
class API,REV,OIDC svc;
class S3,PG,RED store;
class CORE core;
- Git and GitHub CLI (
gh auth login) - Rust (stable, MSVC on Windows)
- Go 1.21+
- Node.js (optional, for building the TS SDK)
winget install Rustlang.Rustup
# If needed:
winget install Microsoft.VisualStudio.2022.BuildTools --silent --override "--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --passive --norestart"
winget install GoLang.Gobrew install rustup-init go gh node
rustup-init -y
gh auth loginAfter installing Rust, restart your shell or add
~/.cargo/bin(Windows:%USERPROFILE%\.cargo\bin) to your PATH.
git clone https://github.com/<YOUR_OWNER>/q-cap
cd q-cap
cargo build --workspaceThe demo subcommand just computes a BLAKE3 “root” over input bytes:
cargo run -p qcap-cli -- hash "hello world"
# -> blake3:7d8d... (hash will vary)You can seed demo capsules and run the registry locally. It exposes:
/— HTML landing page with links/health— JSON status/health.html— HTML status page/index.json— JSON list of seeded.qcapartifacts/index— HTML index listing/artifacts/<name>— static download of seeded artifacts
Quick start:
# Seed demo artifacts (alpha.qcap, beta.qcap)
scripts/seed-registry.sh
# Run the registry
go run services/qcap-registry/main.go
# Optional: smoke test endpoints
scripts/smoke-registry.shcd sdks/ts
npm install --silent || true
npm run buildPlanned commands and features (tracked in GitHub Issues):
qcap init— local key material (Argon2id-protected), fingerprint printoutqcap pack— create.qcaparchive withmanifest.json,payload/,meta/qcap seal— per-file XChaCha20-Poly1305 envelope encryption, recipientsqcap open— verify + decrypt with capability; caveats enforcedqcap grant— mint macaroons with caveats (expiry, audience, paths)qcap revoke— soft revocation with signedrevocations.jsonqcap inspect— summarize manifest, recipients, Merkle rootqcap publish/qcap fetch— push/pull via registry (S3/MinIO)
Server side:
- REST/gRPC endpoints with OpenAPI, Postgres manifest index, Redis cache
- OIDC admin auth; PAT for automation
- Observability: OpenTelemetry traces/metrics; structured logs
SDKs:
- TypeScript (WASM): open/inspect/verify in browser/Node
- Python (cffi): data-pipeline friendly verify/open
A .qcap is a single file (ZIP or tar+gz) containing:
manifest.json— schema version, Merkle root, issuer, policies, metadatapayload/— arbitrary files (optionally encrypted per file)meta/— readme, license, schemas, STAC/OGC tagssignatures/— detached signatures (ed25519) over the manifest & Merkle root
Integrity: BLAKE3 Merkle tree over payload files (root is signed).
Confidentiality: XChaCha20-Poly1305 per file; data keys wrapped to recipients.
Capabilities: Macaroons with caveats (expiry, audience, allowed paths, purpose).
Revocation (soft): signed revocations.json published to the registry.
-
Memory-safe languages (Rust core; Go service)
-
Modern crypto defaults (XChaCha20-Poly1305, BLAKE3, ed25519, Argon2id)
-
Keys:
- Dev: encrypted keyfiles
- Prod: cloud KMS / HSM for issuer roots; rotation documented
-
Supply chain:
- CI includes CodeQL, SBOM (Syft), image scanning (Trivy), signed releases (cosign)
Important: Q-Cap’s security depends on proper key handling and capability distribution. Never commit secrets; review
SECURITY.mdbefore enabling external publication.
Q-Cap is payload-agnostic but designed to carry geospatial content. The MVP will document how to:
- Transport GeoPackage unchanged inside
.qcap - Embed STAC/OGC metadata in
meta/ - Stream-verify large rasters via Merkle while fetching ranges
We welcome issues and PRs. Please read:
CONTRIBUTING.md— how to propose changes & run testsCODE_OF_CONDUCT.md— expected behaviorSECURITY.md— reporting vulnerabilities
Use Conventional Commits (e.g., feat(cli): add grant command) and open an issue before large changes.
- License: Apache-2.0 (see
LICENSE) - Cite:
CITATION.cff(to be added)
# Build everything
cargo build --workspace
# Run CLI demo
cargo run -p qcap-cli -- hash "hello"
# Registry health check
(cd services/qcap-registry && go run .)
curl http://localhost:8080/health
# Explore landing page and index
open http://localhost:8080/ || xdg-open http://localhost:8080/
curl http://localhost:8080/index.json | jq .Prerequisites:
- Rust (cargo) installed
- macOS/Linux shell (commands below use zsh/bash)
Step 1 — Build the workspace:
cargo build --workspaceStep 2 — Prepare a sample payload directory:
mkdir -p /tmp/qcap-demo/payload
echo "hello" > /tmp/qcap-demo/payload/file1.txt
printf "01020304" | xxd -r -p > /tmp/qcap-demo/payload/file2.binStep 3 — Create a 32-byte ed25519 seed (hex) for signing:
echo "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" > /tmp/ed25519.seed.hexStep 4 — Pack a .qcap archive:
cargo run -p qcap-cli -- pack /tmp/qcap-demo/payload --out /tmp/demo.qcap --key /tmp/ed25519.seed.hexStep 5 — Verify the capsule:
cargo run -p qcap-cli -- verify /tmp/demo.qcapStep 6 — Inspect metadata quickly:
cargo run -p qcap-cli -- inspect /tmp/demo.qcapStep 7 — Grant a minimal capability token (allow=read):
cargo run -p qcap-cli -- grant /tmp/demo.qcap --allow read --expires unix-seconds:9999999999 --key /tmp/ed25519.seed.hex --out /tmp/cap.jsonStep 8 — Open (export) the payload using the capability token:
cargo run -p qcap-cli -- open /tmp/demo.qcap --cap /tmp/cap.json --out /tmp/exported
ls -R /tmp/exportedNotes:
- The CLI expects a raw 32-byte ed25519 seed encoded as hex for signing (
--key). - The capability token format is minimal and bound to the Merkle root;
openenforcesallow=read. - Archives are ZIP-based with layout:
manifest.json,payload/…,meta/,signatures/manifest.sig.json.
Q: Can I publish .qcap files publicly without leaking content?
A: Yes—when sealed, payloads are encrypted. Keep manifests private by default unless your policy allows public manifests.
Q: Does Q-Cap replace a Protected B cloud environment? A: Not automatically. It can reduce exposure by encrypting artifacts at rest and in transit, but operational constraints and classification rules still apply. See ADR-0009 once finalized.