Files
ietf-draft-analyzer/workspace/packages/ect/README.md
Christian Nennemann 3a139dfc7e feat: ACT/ECT strategy, package restructure, draft -01/-02 prep
Strategic work for IETF submission of draft-nennemann-act-01 and
draft-nennemann-wimse-ect-02:

Package restructure:
- move ACT and ECT refimpls to workspace/packages/{act,ect}/
- ietf-act and ietf-ect distribution names (sibling packages)
- cross-spec interop test plan (INTEROP-TEST-PLAN.md)

ACT draft -01 revisions:
- rename 'par' claim to 'pred' (align with ECT)
- rename 'Agent Compact Token' to 'Agent Context Token' (semantic
  alignment with ECT family)
- add Applicability section (MCP, OpenAI, LangGraph, A2A, CrewAI)
- add DAG vs Linear Delegation Chains section (differentiator vs
  txn-tokens-for-agents actchain, Agentic JWT, AIP/IBCTs)
- add Related Work: AIP, SentinelAgent, Agentic JWT, txn-tokens-for-agents,
  HDP, SCITT-AI-agent-execution
- pin SCITT arch to -22, note AUTH48 status

Outreach drafts:
- Emirdag liaison email (SCITT-AI coordination)
- OAuth ML response on txn-tokens-for-agents-06

Strategy document:
- STRATEGY.md with phased action plan, risk register, timeline

Submodule:
- update workspace/drafts/ietf-wimse-ect pointer to -02 commit
2026-04-12 07:33:08 +02:00

3.5 KiB

WIMSE ECT — Python Reference Implementation

Python reference implementation of Execution Context Tokens (ECTs) for WIMSE. Implements ECT creation (ES256), verification (Section 7), DAG validation (Section 6), and an in-memory audit ledger (Section 9).

Layout

python/
├── pyproject.toml
├── ect/                 # library
│   ├── __init__.py
│   ├── types.py         # Payload, constants
│   ├── create.py        # create(), generate_key()
│   ├── verify.py        # parse(), verify(), VerifyOptions
│   ├── dag.py           # validate_dag(), ECTStore, DAGConfig
│   ├── ledger.py        # Ledger, MemoryLedger
│   ├── config.py        # Config, load_config_from_env()
│   ├── jti_cache.py     # JTICache for replay protection
│   └── validate.py      # validate_ext, valid_uuid, validate_hash_format
├── tests/
│   ├── test_create.py
│   └── test_dag.py
├── testdata/
│   └── valid_root_ect_payload.json
└── demo.py              # two-agent workflow demo

Install

cd refimpl/python && pip install -e .

Usage

from ect import (
    Payload,
    create,
    generate_key,
    CreateOptions,
    verify,
    VerifyOptions,
    MemoryLedger,
)

cfg = load_config_from_env()
key = generate_key()
payload = Payload(
    iss="spiffe://example.com/agent/a",
    aud=["spiffe://example.com/agent/b"],
    iat=int(time.time()),
    exp=int(time.time()) + 600,
    jti="550e8400-e29b-41d4-a716-446655440000",
    exec_act="review_spec",
    pred=[],
    ext={
        "pol": "policy_v1",
        "pol_decision": "approved",
    },
)
compact = create(payload, key, cfg.create_options("agent-a-key"))

store = MemoryLedger()
opts = cfg.verify_options()
opts.verifier_id = "spiffe://example.com/agent/b"
opts.resolve_key = lambda kid: key.public_key() if kid == "agent-a-key" else None
opts.store = store
parsed = verify(compact, opts)
store.append(compact, parsed.payload)

Demo

cd refimpl/python && python3 demo.py

Tests

cd refimpl/python && python3 -m pytest tests/ -v

Unit tests require 90% coverage minimum (pytest is configured with --cov-fail-under=90 in pyproject.toml). Install dev deps: pip install -e ".[dev]". Uncovered lines are mainly abstract base methods and a few verify branches that need manually built tokens.

draft-01 claim changes

-00 (previous) -01 (current) Notes
par pred Predecessor task IDs
pol, pol_decision removed (use ect_ext) Policy claims moved to extension object
sub not defined Standard JWT claim, not part of ECT spec
typ: wimse-exec+jwt typ: exec+jwt (preferred) Both accepted for backward compat
max_par_length max_pred_length Renamed to match pred claim

Production configuration (environment)

Same env vars as the Go refimpl: ECT_IAT_MAX_AGE_MINUTES, ECT_IAT_MAX_FUTURE_SEC, ECT_DEFAULT_EXPIRY_MIN, ECT_JTI_REPLAY_CACHE_SIZE, ECT_JTI_REPLAY_TTL_MIN.

Replay cache (multi-instance)

The provided JTI cache is in-memory only. For multiple verifier instances, use a shared store (Redis, DB) and pass a jti_seen callable that checks/records JTIs there. See refimpl/README for an overview.

Dependencies

  • PyJWT, cryptography (ES256).

License

Same as the Internet-Draft (IETF Trust). Code under Revised BSD per BCP 78/79.