Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .cursor/rules/no-credentials-in-docs.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
description: Prevent credentials and secrets in committed documentation
alwaysApply: true
---

# No credentials in documentation

When creating or editing files that may be committed (especially `*.md`, `*.mdx`, `*.example`, `README*`, `NOTES*`, `docs/**`), **never** embed real secrets.

## Do not include

- Passwords, passphrases, API keys, tokens, cookies, private keys, WIFs
- Basic-auth pairs in curl/examples (`-u realuser:realpassword`)
- Values copied from the user's `.env`, `NOTES.md`, `setup_*.sh`, Docker `-e` flags, or chat history
- Production hostnames/IPs tied to identifiable infra (prefer `127.0.0.1`, `localhost`, `example.com`)

## Use placeholders instead

```bash
# ❌ BAD — real credential from local setup
curl -u subs:NeverASecret! http://127.0.0.1:7777/spaces/@space/pipeline

# ✅ GOOD — env vars or generic placeholders
curl -u "$SUBS_BASIC_AUTH_USER:$SUBS_BASIC_AUTH_PASSWORD" "$BASE/spaces/$SPACE/pipeline"

# ✅ GOOD — document optional auth without values
# If basic auth is enabled: -u "$SUBS_BASIC_AUTH_USER:$SUBS_BASIC_AUTH_PASSWORD"
curl "$BASE/spaces/$SPACE/pipeline"
```

```bash
# ❌ BAD
-e SUBS_BASIC_AUTH_PASSWORD=Whatever84

# ✅ GOOD
-e SUBS_BASIC_AUTH_PASSWORD=change-me
# or reference .env.example without real values
```

## Before finishing doc changes

1. Search the diff for patterns: `password`, `secret`, `token`, `api_key`, `-u `, `Bearer `, `BEGIN.*PRIVATE KEY`, `xprv`, `WIF`
2. Replace any value that came from the user's environment with a placeholder or env-var reference
3. If a real secret was already written, redact it and tell the user to rotate the credential

## Safe sources

- `.env.example` with obvious placeholders (`change-me`, `your-password-here`)
- Variable **names** and config keys (e.g. `SUBS_SPACED_RPC_PASSWORD`) without real values
- Public URLs documented by the project (e.g. fabric relay seeds)
10 changes: 9 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,21 @@ target
# Local operator state, never part of an image.
data
testrig-data
datamad
*.bin
*.priv
*.subs
*.subs.c
*.sdb

# Secrets and local notes (keep README for image docs if needed).
.env
.env.*
NOTES.md
*.md
!README.md

.DS_Store
**/.DS_Store
screenshot.png
LICENSE
LICENSE
48 changes: 48 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copy to .env and adjust, or export variables in your shell.
# CLI flags take precedence over environment variables.

# --- subs ---
SUBS_PORT=7777
SUBS_DATA_DIR=./data
SUBS_WALLET=my-wallet
SUBS_SPACED_RPC_URL=http://127.0.0.1:7225
# SUBS_SPACED_RPC_USER=testuser
# SUBS_SPACED_RPC_PASSWORD=secret
# SUBS_SPACED_RPC_COOKIE=/path/to/.cookie
# Optional HTTP Basic auth for the UI/API. Set BOTH to enable (GET /health stays anonymous).
# SUBS_BASIC_AUTH_USER=admin
# SUBS_BASIC_AUTH_PASSWORD=change-me
# In Docker, subs-prover and registry-server run in the same container as subs by default.
SUBS_PROVER_ENDPOINT=http://127.0.0.1:8888
SUBS_REGISTRY_ENDPOINT=http://127.0.0.1:8081
# SUBS_START_PROVER=1
# SUBS_START_REGISTRY=1
# SUBS_PROVER_SERVER=1
# SUBS_ENV_FILE=.env
# SUBS_TEST_RIG=1
# Block publish until commitments reach 150 on-chain confirmations.
# Default: false (unset, empty, 0, false, no, off). Truthy: 1, true, yes, on.
# SUBS_PUBLISH_REQUIRE_FINALIZED=1
# SUBS_TEST_RIG_DIR=./testrig-data

# --- subs-prover ---
# SUBS_PROVER_SERVER=1
SUBS_PROVER_PORT=8888
# SUBS_PROVER_ENV_FILE=.env
# SUBS_PROVER_INPUT=request.json
# SUBS_PROVER_OUTPUT=receipt.bin
# Optional bearer auth for the prover (Authorization: Bearer <token>).
# When set, all routes including /health require the token.
# PROVER_AUTH_TOKEN=change-me
# Opt-in startup calibration (blocks listen until done). Also --calibrate.
# PROVER_CALIBRATE=1

# --- registry-server (example) ---
REGISTRY_SERVER_PORT=8081
# Both keys are required and must differ (see examples/registry-server/README.md).
# REGISTRY_API_KEY=change-me-intake
# SUBSD_API_KEY=change-me-subsd
# REGISTRY_SERVER_ENV_FILE=.env

# --- logging (all components) ---
# RUST_LOG=subs=info,subs_prover=info,registry_server=info,tower_http=debug
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.env
.env.*
!.env.example
.DS_Store
.vscode
target/
Expand All @@ -8,4 +11,9 @@ target/
*.sdb
.idea
testrig-data
data
data/
datamad/
datamadd/
NOTES.md
.cargo/
subspaces.tar
29 changes: 29 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
[workspace]
resolver = "2"
members = ["core", "prover", "types", "subs", "examples/registry-server"]
members = [
"config-origins",
"core",
"prover",
"types",
"subs",
"examples/registry-server",
"tools/wif-to-hex",
]

[workspace.dependencies]
# Internal crates
Expand Down Expand Up @@ -31,7 +39,8 @@ serde_json = "1.0"
anyhow = "1.0"
hex = "0.4"
borsh = { version = "1.5", default-features = false, features = ["derive"] }
clap = { version = "4.5", features = ["derive"] }
clap = { version = "4.5", features = ["derive", "env"] }
dotenvy = "0.15"
tokio = { version = "1" }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
Expand Down
132 changes: 132 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# syntax=docker/dockerfile:1

# Rust toolchain on Alpine (musl) for release binaries.
FROM rust:1-alpine3.21 AS builder-base

ARG CARGO_BUILD_JOBS=1

RUN apk add --no-cache \
build-base \
musl-dev \
git \
openssl-dev \
openssl-libs-static \
pkgconf \
clang \
llvm-dev \
lld \
libatomic \
ca-certificates

WORKDIR /app
ENV CARGO_BUILD_JOBS=${CARGO_BUILD_JOBS}
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
ENV RUSTFLAGS="-C link-arg=-fuse-ld=lld"

# subs + registry share a target/ tree (small compared to subs-prover).
FROM builder-base AS builder-subs

ARG ENABLE_REGISTRY=true

COPY . .

RUN set -eux; \
cargo build --release -p subs; \
if [ "$ENABLE_REGISTRY" != "false" ]; then \
cargo build --release -p registry-server; \
fi; \
mkdir -p /out; \
cp target/release/subs /out/; \
if [ "$ENABLE_REGISTRY" != "false" ]; then \
cp target/release/registry-server /out/; \
fi; \
cargo clean

# subs-prover (RISC Zero) in a fresh stage so target/ does not stack on top of subs.
FROM builder-base AS builder-prover

ARG ENABLE_PROVER=true
ARG GPU_ACCELERATION=none
ARG TARGETARCH

COPY . .

RUN set -eux; \
if [ "$ENABLE_PROVER" = "false" ]; then \
mkdir -p /out; \
exit 0; \
fi; \
if [ "$TARGETARCH" = "arm64" ]; then \
export CFLAGS="-mno-outline-atomics"; \
export CXXFLAGS="-mno-outline-atomics"; \
export CMAKE_C_FLAGS="-mno-outline-atomics"; \
export CMAKE_CXX_FLAGS="-mno-outline-atomics"; \
export RUSTFLAGS="-C link-arg=-fuse-ld=lld -C target-feature=-outline-atomics"; \
else \
export RUSTFLAGS="-C link-arg=-fuse-ld=lld"; \
fi; \
case "$GPU_ACCELERATION" in \
none) cargo build --release -p subs-prover ;; \
metal) cargo build --release -p subs-prover --features metal ;; \
cuda) cargo build --release -p subs-prover --features cuda ;; \
*) echo "Invalid GPU_ACCELERATION=$GPU_ACCELERATION (expected none, metal, or cuda)" >&2; exit 1 ;; \
esac; \
mkdir -p /out; \
cp target/release/subs-prover /out/; \
cargo clean

FROM alpine:3.21

ARG ENABLE_PROVER=true
ARG ENABLE_REGISTRY=true
ARG GPU_ACCELERATION=none

RUN apk add --no-cache ca-certificates libgcc tini \
&& addgroup -S subs \
&& adduser -S subs -G subs

COPY --from=builder-subs /out/subs /usr/local/bin/subs

RUN --mount=type=bind,from=builder-subs,source=/out,target=/subs-out \
--mount=type=bind,from=builder-prover,source=/out,target=/prover-out \
set -eux; \
if [ "$ENABLE_REGISTRY" != "false" ] && [ -f /subs-out/registry-server ]; then \
cp /subs-out/registry-server /usr/local/bin/registry-server; \
fi; \
if [ "$ENABLE_PROVER" != "false" ] && [ -f /prover-out/subs-prover ]; then \
cp /prover-out/subs-prover /usr/local/bin/subs-prover; \
fi; \
: > /etc/subs-image.env; \
if [ "$ENABLE_PROVER" != "false" ]; then \
echo "SUBS_START_PROVER=1" >> /etc/subs-image.env; \
echo "SUBS_PROVER_ENDPOINT=http://127.0.0.1:8888" >> /etc/subs-image.env; \
echo "SUBS_PROVER_SERVER=1" >> /etc/subs-image.env; \
echo "SUBS_PROVER_GPU_ACCELERATION=${GPU_ACCELERATION}" >> /etc/subs-image.env; \
else \
echo "SUBS_START_PROVER=0" >> /etc/subs-image.env; \
fi; \
if [ "$ENABLE_REGISTRY" != "false" ]; then \
echo "SUBS_START_REGISTRY=1" >> /etc/subs-image.env; \
echo "SUBS_REGISTRY_ENDPOINT=http://127.0.0.1:8081" >> /etc/subs-image.env; \
else \
echo "SUBS_START_REGISTRY=0" >> /etc/subs-image.env; \
fi

COPY docker/entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh \
&& mkdir -p /data \
&& chown -R subs:subs /data

WORKDIR /data
USER subs

ENV SUBS_DATA_DIR=/data
ENV SUBS_PORT=7777
ENV SUBS_PROVER_PORT=8888
ENV REGISTRY_SERVER_PORT=8081

EXPOSE 7777 8888 8080 8081

ENTRYPOINT ["/sbin/tini", "--", "/entrypoint.sh"]
CMD ["subs"]
Loading