Restructure refimpl into go-lang and python subdirectories
Move Go reference implementation to refimpl/go-lang/ and add new Python reference implementation in refimpl/python/. Update build.sh with renamed draft and simplified tool paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
# WIMSE Execution Context Tokens — Reference Implementation
|
||||
# WIMSE Execution Context Tokens — Reference Implementations
|
||||
|
||||
This directory contains a **reference implementation** of [Execution Context Tokens (ECTs)](../draft-nennemann-wimse-execution-context-00.txt) for the WIMSE (Workload Identity in Multi System Environments) draft. It implements ECT creation, verification, DAG validation, and an in-memory audit ledger.
|
||||
This directory contains **reference implementations** of [Execution Context Tokens (ECTs)](../draft-nennemann-wimse-execution-context-00.txt) for the WIMSE (Workload Identity in Multi System Environments) draft. Each refimpl provides ECT creation, verification, DAG validation, and an in-memory audit ledger.
|
||||
|
||||
## Scope
|
||||
## Implementations
|
||||
|
||||
| Language | Path | Description |
|
||||
|----------|-----------|-------------|
|
||||
| **Go** | [go-lang/](go-lang/) | Production-ready Go library and demo. Config via env; optional JTI replay cache. |
|
||||
| **Python** | [python/](python/) | Python 3.9+ library and demo. Same API surface and env-based config. |
|
||||
|
||||
## Scope (all refimpls)
|
||||
|
||||
- **ECT format**: JWT (JWS Compact Serialization) with required/optional claims per the spec (Section 4).
|
||||
- **Creation**: Build and sign ECTs with ES256; `kid` and `typ: wimse-exec+jwt` in the JOSE header.
|
||||
@@ -10,83 +17,28 @@ This directory contains a **reference implementation** of [Execution Context Tok
|
||||
- **DAG validation**: Section 6 (uniqueness, parent existence, temporal ordering, acyclicity, parent policy).
|
||||
- **Ledger**: Interface plus in-memory append-only store (Section 9).
|
||||
|
||||
No WIT/WPT issuance or full WIMSE stack; the refimpl uses key resolution only. Suitable for conformance testing and as a template for production integrations.
|
||||
No WIT/WPT issuance or full WIMSE stack; refimpls use key resolution only. Suitable for conformance testing and as a template for production integrations.
|
||||
|
||||
## Layout
|
||||
### Replay cache (multi-instance)
|
||||
|
||||
```
|
||||
refimpl/
|
||||
├── go.mod
|
||||
├── README.md
|
||||
├── ect/ # library
|
||||
│ ├── types.go # Payload, Audience, constants
|
||||
│ ├── audience.go # aud marshal/unmarshal
|
||||
│ ├── create.go # Create(), GenerateKey()
|
||||
│ ├── verify.go # Parse(), Verify(), VerifyOptions
|
||||
│ ├── dag.go # ValidateDAG(), ECTStore
|
||||
│ ├── ledger.go # Ledger, MemoryLedger
|
||||
│ └── *_test.go
|
||||
├── testdata/
|
||||
│ └── valid_root_ect_payload.json
|
||||
└── cmd/
|
||||
└── demo/ # two-agent workflow demo
|
||||
└── main.go
|
||||
```
|
||||
The optional JTI replay cache (`JTICache` / `JtiCache`) is **in-memory only**. For multiple verifier instances behind a load balancer, replay detection must be shared. Use a distributed store (e.g. Redis, database) and implement the same contract as `JTISeen`: a function that returns true if the JTI was already seen, and ensure each verified JTI is recorded (e.g. with TTL). See go-lang/README and python/README for configuration and how to plug in a custom `JTISeen` / `jti_seen`.
|
||||
|
||||
## Usage
|
||||
## Quick start
|
||||
|
||||
### Library
|
||||
|
||||
```go
|
||||
import "github.com/nennemann/ect-refimpl/ect"
|
||||
|
||||
// Create
|
||||
key, _ := ect.GenerateKey()
|
||||
payload := &ect.Payload{
|
||||
Iss: "spiffe://example.com/agent/a",
|
||||
Aud: ect.Audience{"spiffe://example.com/agent/b"},
|
||||
Iat: time.Now().Unix(),
|
||||
Exp: time.Now().Add(10*time.Minute).Unix(),
|
||||
Jti: "uuid-...",
|
||||
Tid: "task-001",
|
||||
ExecAct: "review_spec",
|
||||
Par: []string{},
|
||||
Pol: "policy_v1",
|
||||
PolDecision: ect.PolDecisionApproved,
|
||||
}
|
||||
compact, err := ect.Create(payload, key, ect.CreateOptions{KeyID: "agent-a-key"})
|
||||
|
||||
// Verify (with DAG store)
|
||||
store := ect.NewMemoryLedger()
|
||||
resolver := func(kid string) (*ecdsa.PublicKey, error) { ... }
|
||||
parsed, err := ect.Verify(compact, ect.VerifyOptions{
|
||||
VerifierID: "spiffe://example.com/agent/b",
|
||||
ResolveKey: resolver,
|
||||
Store: store,
|
||||
})
|
||||
store.Append(compact, parsed.Payload)
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
From the repo root (or `refimpl/`):
|
||||
**Go**
|
||||
|
||||
```bash
|
||||
cd refimpl && go run ./cmd/demo
|
||||
cd refimpl/go-lang && go run ./cmd/demo
|
||||
go test ./...
|
||||
```
|
||||
|
||||
Runs a two-agent flow: Agent A issues a root ECT, Agent B verifies and appends it, then issues a child ECT; verification uses DAG validation against the ledger.
|
||||
|
||||
## Tests
|
||||
**Python**
|
||||
|
||||
```bash
|
||||
cd refimpl && go test ./...
|
||||
cd refimpl/python && pip install -e . && python3 demo.py
|
||||
python3 -m pytest tests/ -v
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [go-jose/v4](https://github.com/go-jose/go-jose/v4) for JWS (ES256) and JWK handling. No custom crypto.
|
||||
|
||||
## Specification
|
||||
|
||||
- **Draft**: `draft-nennemann-wimse-execution-context-00`
|
||||
|
||||
Reference in New Issue
Block a user