Skip to content
Draft
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
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ MAPLE_PORT=8080
# Maple Backend Configuration
# Production: https://enclave.trymaple.ai
# Development: https://enclave.secretgpt.ai
# Local: http://localhost:3000
# Local: use `just run-local`; plain HTTP mock attestation is compile-time
# gated and is never enabled in release, Docker, or embedded Maple builds.
MAPLE_BACKEND_URL=https://enclave.trymaple.ai

# Authentication
Expand Down
31 changes: 30 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,40 @@ Maple Proxy is a lightweight OpenAI-compatible proxy server that forwards reques
- Handles streaming responses for chat completions
- Transforms responses to OpenAI format

### TEE attestation boundary

TEE measurement authorization is owned by the OpenSecret SDK. Maple Proxy
should only call `perform_attestation_handshake`; do not add a proxy-specific
PCR allowlist or Sigstore/Rekor verifier.

The intended SDK handshake authenticates the AWS Nitro attestation document,
compares the complete PCR0/PCR1/PCR2 tuple with a release snapshot embedded in
the SDK, and only then accepts the enclave public key and performs key exchange.
There is no runtime Sigstore/Rekor or release-metadata network lookup. At SDK
update time, the updater verifies the release manifest and Cosign bundle,
including the expected signing identity and Rekor evidence, before generating
the embedded snapshot.

Mock attestation is available only through the explicitly named
`insecure-local-mock-attestation` Cargo feature. Keep it disabled in release,
Docker, and embedded Maple builds; only `just run-local` opts in.

Rekor supplies tamper-evident transparency-log evidence for the signed release
statement used to generate that snapshot. It does not itself prove Nix
reproducibility, release freshness, rollback prevention, or revocation.

This integration branch pins an exact reviewed SDK commit with default features
disabled. That staging commit deliberately contains an empty release snapshot,
so remote handshakes fail closed. Before release, replace the pin with a
snapshot-bearing reviewed commit or published crate; do not invent an
unpublished version or vendor the SDK here.

### Request Flow

1. Client sends OpenAI-compatible request to proxy
2. Proxy extracts API key (from header or default config)
3. Creates OpenSecret client and performs TEE attestation
3. Creates an OpenSecret client and delegates TEE authentication, release
authorization, and key exchange to the SDK
4. Forwards request to Maple backend (enclave.trymaple.ai or configured URL)
5. Streams response back to client in OpenAI format

Expand Down
3 changes: 1 addition & 2 deletions Cargo.lock

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

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@ path = "src/lib.rs"
name = "maple-proxy"
path = "src/main.rs"

[features]
default = []
# Explicit development-only opt-in. Release, Docker, and embedded Maple builds
# use default features and cannot accept mock attestation documents.
insecure-local-mock-attestation = ["opensecret/mock-attestation"]

[dependencies]
# OpenSecret SDK
opensecret = "3.4.0"
opensecret = { git = "https://github.com/OpenSecretCloud/OpenSecret-SDK", rev = "1bd7196043b26b3a2f8080534bd14031afcd5cc8", default-features = false }

# Web server
axum = { version = "0.8.4", features = ["http2", "macros"] }
Expand Down
55 changes: 50 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Environment (TEE) processing.
## 🚀 Features

- **OpenAI-Compatible Surface** - Models, chat completions, and embeddings endpoints
- **Secure TEE Processing** - All requests processed in secure enclaves
- **Attested TEE Transport** - The OpenSecret SDK establishes an attested,
encrypted channel before inference requests are forwarded
- **Lossless Chat Parameters** - Provider-specific request fields pass through unchanged
- **Streaming and Non-Streaming** - Supports both chat completion response modes
- **Flexible Authentication** - Environment variables or per-request API keys
Expand Down Expand Up @@ -44,7 +45,7 @@ Set environment variables or use command-line arguments:
# Environment Variables
export MAPLE_HOST=127.0.0.1 # Server host (default: 127.0.0.1)
export MAPLE_PORT=8080 # Server port (default: 8080)
export MAPLE_BACKEND_URL=http://localhost:3000 # Maple backend URL (prod: https://enclave.trymaple.ai)
export MAPLE_BACKEND_URL=https://enclave.trymaple.ai # Maple backend URL
export MAPLE_API_KEY=your-maple-api-key # Default API key (optional)
export MAPLE_DEBUG=true # Enable debug logging
export MAPLE_ENABLE_CORS=true # Enable CORS
Expand All @@ -57,6 +58,10 @@ Or use CLI arguments:
cargo run -- --host 0.0.0.0 --port 8080 --backend-url https://enclave.trymaple.ai
```

For an unsigned local backend, use `just run-local`. That recipe alone enables
the explicitly named `insecure-local-mock-attestation` Cargo feature. Generic,
release, Docker, and embedded Maple builds leave the feature disabled.

## 🛠️ Usage

### Using as a Binary
Expand Down Expand Up @@ -453,9 +458,49 @@ cargo run
```

1. **Client** makes standard OpenAI API calls to localhost
2. **Maple Proxy** handles authentication and TEE handshake
3. **Requests** are securely forwarded to Maple's TEE infrastructure
4. **Responses** are streamed back to the client in OpenAI format
2. **Maple Proxy** handles authentication and asks the OpenSecret SDK to
establish the TEE channel
3. **OpenSecret SDK** authenticates and authorizes the enclave before accepting
its key and completing key exchange
4. **Requests** are encrypted and forwarded to Maple's TEE infrastructure
5. **Responses** are streamed back to the client in OpenAI format

### TEE release authorization

The Sigstore/Rekor release-authorization work belongs in the OpenSecret SDK,
not in Maple Proxy. For each non-local backend, the SDK is expected to:

1. verify the AWS Nitro attestation document, certificate chain, nonce, and
signature;
2. extract and validate the complete PCR0/PCR1/PCR2 measurement tuple;
3. compare that tuple with the release snapshot embedded in the SDK; and
4. accept the enclave public key and perform key exchange only after the tuple
is present in that snapshot.

Maple Proxy continues to call `perform_attestation_handshake`; it neither
maintains a second PCR allowlist nor implements a separate Sigstore verifier.
Keeping this policy in the SDK gives every Rust SDK consumer the same
fail-closed authorization boundary before application data is sent.

There is no Sigstore, Rekor, or other release-metadata network lookup during a
runtime handshake. At SDK update time, the release-snapshot updater verifies
the release manifest and Cosign bundle, including the expected signing identity
and Rekor evidence, before generating the embedded snapshot. Consumers then
review and pin the SDK release containing that generated snapshot.

Sigstore makes a release statement and its signing identity tamper-evident in
an append-only transparency log. It does **not** prove that an artifact was
reproducibly built, and it does **not** make an old, previously authorized
release fresh. Reproducibility remains a separate Nix rebuild/compare property;
rollback prevention, revocation, or minimum-version policy must also be handled
separately.

> **Integration status:** this branch pins the exact reviewed SDK integration
> commit with default features disabled. Its embedded release snapshot is
> intentionally empty, so remote handshakes fail closed. Update the pin to a
> reviewed snapshot-bearing commit or published crate after the first signed
> backend release; do not merge or publish this staging state as a working
> production proxy.

## 📝 License

Expand Down
3 changes: 2 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ run-with-backend url:

# Run pointing to local backend
run-local:
@just run-with-backend "http://localhost:3000"
@echo "🚧 Starting with development-only mock attestation enabled"
@bash -c 'set -a; source .env 2>/dev/null; set +a; MAPLE_BACKEND_URL=http://localhost:3000 cargo run --features insecure-local-mock-attestation'

# Run pointing to production backend
run-prod:
Expand Down