burstdocs
DEVELOPERS / Core concepts

Eight-area ecosystem increment

Updated 2026-10-29. The previous roadmap listed six implementation steps. This increment adds build/release preparation and troubleshooting as areas 7–8. It implements a bounded private-network development slice; it does not complete every V1 requirement or every repository.

AreaImplementedVerification / limit
1. AuthorizationPersistent groups, scoped membership, allow/deny grants, expiry/revocation, namespace discovery, read/write/publish enforcementCurrent authority is queried on every operation; group removal/revocation denies the next read and in-flight reads reauthorize before key release
2. Identity/persistenceSQLite migration, PostgreSQL adapter, CSR renewal, overlapping trust bundles, managed-certificate enrollment/refresh without a CA private keyDevelopment and externally signed certificate fixtures tested; live SPIRE deployment and production DB roles/HA remain separate
3. Nodes/RPCGenerated Protobuf/gRPC storage service, mTLS URI identities, directory registration, bounded calls, capacity reservations, immutable acknowledged blobsThree-node TLS integration, role/network/path/digest rejection; no relay/NAT traversal or public peers
4. PoliciesPinned Starlark interpreter, signed immutable policy versions, activation, execution budgets, process isolation and static obligationsNo host/network/load APIs; Linux worker caps described below; production interpreter/sandbox security review remains required
5. Encrypted storageRandom per-object AES-GCM keys, scope AAD, separately wrapped keys, verified replicas, staged uploads, repair and expiry/deletion queues1 MiB object limit; local or Vault Transit wrapping; bounded peer chunk streams; no resumable transfers or erasure coding
6. Lifecycle testsLogin, enroll three nodes, publish policy, encrypted upload, group read, revocation, replacement-node repair, expiry and deletionCovers policy changes during upload, revocation during fetch, corruption fallback, authority loss and restart cases
7. Build/releaseSix command builds, SHA-256 manifest, pinned RPC generator tools, CI and a publication prerequisite gateNo GitHub repositories were created/published; namespace, dependency versions and licenses must be finalized
8. TroubleshootingFive log levels, text/JSON output, request IDs propagated to RPC, status/maintenance APIs, protected separate pprof listenerSecret/body logging is excluded; diagnostics is opt-in and loopback-only

Run the data slice

Follow identity setup first to configure OIDC and local HTTPS/CA certificates. Build the toolkit and create a wrapping key once:

sh
sh scripts/build.sh dev
(umask 077; set -C; openssl rand 32 > .burst/object-key)

Do not replace an existing wrapping key: it is required to decrypt stored objects. Startup pins its fingerprint in metadata and rejects a different key. Add these flags to the control-service command in identity-slice.md:

sh
-policy-worker /absolute/path/to/burst-kit/dist/burst-policy-worker \
-object-key-file .burst/object-key \
-log-level info -log-format json

On macOS, add -development-policy-soft-memory explicitly. Hard worker limits are not silently relaxed on unsupported platforms. This mode is for development with trusted policy authors, not a hostile-workload production boundary.

The browser console now supports key registration, signed policy publication, groups/members/grants, object upload/download/deletion, storage registration and maintenance. Namespace browsing requires space.read; object.read alone permits a known object path but not namespace discovery. Root grant issuance requires a network operator. Set delegable: true on a root to authorize narrower child grants using parent_grant_id. Child grants must preserve action and narrow resource/expiry; at most eight hops are accepted. Revocation, expiry, issuer disablement and parent group removal invalidate descendants on the next authorization. grant.manage alone permits group administration; it does not permit minting root grants. Operators and original issuers may revoke grants. Snapshots are bounded to 4096 grants per space.

Publish a policy

Generate an Ed25519 key, export its public registration, and upload that registration JSON in the console:

sh
dist/burstpolicy -key .burst/policy.key -generate-key
dist/burstpolicy -key .burst/policy.key -public-key > .burst/public-key.json

Create policy.star:

python
def evaluate(ctx):
    return {
        "allow": ctx["action"] in ["read", "write"],
        "replicas": 3,
        "domains": 3,
        "ttl_seconds": 3600,
        "regions": ["local"],
    }

Sign it using the network, space ID and principal ID shown by the console:

sh
dist/burstpolicy -key .burst/policy.key -source policy.star \
  -network devnet -space SPACE_ID -principal PRINCIPAL_ID -revision 1 \
  > .burst/signed-policy.json

Upload the signed JSON through the console. Subsequent publications require the next revision. Public keys are registered to the authenticated principal; publication still requires its current contract.publish grant. Signing encoding remains the provisional versioned Go format; no cross-language signing compatibility is promised.

Policy input keys have a stable insertion order: network_id, space_id, principal, action, now. now is supplied by authority. allow may depend on inputs. Replicas, domains, TTL and region obligations are pinned at publication; later evaluations that vary them deny. This prevents per-caller weakening of storage requirements. Shortening retention reduces existing object expiry transactionally. Increasing retention never extends existing expiry or resurrects expired data.

Run three nodes

Enroll each node with its own private key using the identity guide. Nodes receive both client/server authentication EKUs. Start each node with its enrolled certificate and the CA bundle:

sh
dist/burstnode -listen 127.0.0.1:9443 -directory .burst/node1 \
  -tls-cert node1.crt -tls-key node1.key -trust-bundle .burst/pki/ca.crt \
  -network devnet -log-level info -log-format json

Use distinct ports/directories/identities for node2 and node3. Register their endpoints, region local, capacity and distinct failure domains in the console. Failure domains are operator assertions, not independently attested geography/hardware. The fourth replacement node used in recovery tests is a fresh compliant node; durability is reported degraded if only two required domains survive.

Private remote listeners require burstnode -allow-private-listen; no public peer admission is implemented. Storage RPCs accept only the configured network's service identity spiffe://TRUST_DOMAIN/network/NETWORK/service/controlplane. Nodes use the distinct /node/NODE_ID namespace; enrolling a node named controlplane grants no service role. URI identity verification replaces DNS-name verification and checks the configured chain, EKU, expiry and exact SPIFFE ID, including after each successful RPC on a reused connection.

Upload/download through the console. All selected replicas must durably acknowledge before commit. Permission, membership, endpoint/placement and policy revision are rechecked before visibility. Losing authority denies new key release. Failed uploads retain a cleanup record; maintenance deletes abandoned staging copies after a one-minute grace interval. Capacity accounting includes staged and not-yet-deleted replicas.

Maintenance runs every 30 seconds by default; -maintenance-interval 0 disables the ticker. A protected API/console action also runs it. It repairs from verified ciphertext and records degraded objects if required placement cannot be met. Expiry denies reads before maintenance runs; maintenance drops the active wrapped-key reference, creates persistent peer tombstones and retries deletion of unavailable replicas. Active metadata and peer tombstones are retained. This is not a guarantee of secure physical erasure from old database pages, exported plaintext, keys retained elsewhere or backups. Backup/tombstone restoration is still an outstanding operational design.

Additional API routes

All browser mutations retain session/Origin/CSRF/idempotency checks. Object upload allows a 2 MiB JSON body with at most 1 MiB decoded data; policy publication allows a 256 KiB JSON body and at most 64 KiB source. Other mutations retain a 64 KiB limit.

Route under /v1/networks/{network}Behavior
POST /spaces/{space}/groups{name} → group ID
POST /spaces/{space}/groups/{group}/members{principal_id, remove?}; target must exist in the principal registry
POST /spaces/{space}/grants{subject_kind,subject_id,resource,action,effect,expires_at}; user/group subject, exact space/object scope, allow/deny, maximum 24 hours
POST /spaces/{space}/grants/{grant}/revoke{}; effective immediately for subsequent permission checks
POST /keysOwn {key_id,public_key_hex}; requires operator or effective publication authority
POST /spaces/{space}/policies{artifact,source,signature,key_id}; signature is base64 in JSON
POST /nodes/{node}/directory{endpoint,region,failure_domain,capacity_bytes}; operator only and active membership required
POST /spaces/{space}/objects{data} with base64 bytes → object ID, expiry and policy revision
GET /spaces/{space}/objects/{object}Authorized {object_id,data}; 410 after expiry, 404 after logical deletion
POST /spaces/{space}/objects/{object}/delete{}; logical deletion and active wrapped-key removal; replica deletion follows maintenance
POST /node/renewmTLS + {csr_pem} + idempotency key; proof of old and new keys; superseded certificates cannot start another renewal
POST /enrollments/{enrollment}/attestApproved bootstrap token + already trusted mTLS identity; no local signing
POST /node/attestRefresh an active attested membership with a fresh managed certificate; older NotBefore values cannot roll back rotation
GET /statusOperator counts for nodes, grants, objects, staging and pending deletion; configured worker/data-plane flags
POST /reconcileOperator maintenance run; {} plus fresh idempotency key for each new run

Vault Transit custody can replace the local object key for a new store; see the contracts guide. Existing custody cannot be changed without an explicit migration. The offline application worker and its live isolation test are described in the worker guide.

Space creation seeds the owner with 24-hour grants. Renew administrative grants explicitly; ownership itself does not bypass object authorization. Deny overrides allow. Network operators can manage entitlements but do not implicitly bypass data-read grants or contracts.

PostgreSQL and managed identity

Select -database-backend postgres and supply BURST_POSTGRES_DSN. Initialize with migration-owner credentials using:

sh
dist/burst -database-backend postgres -migrate-only

The runtime schema is burst_runtime_v1, version 4. It is separate from the earlier planning prototype at burst/migrations/001_control.sql; do not apply that prototype as the runtime migration. Normal startup does not migrate PostgreSQL unless explicitly requested. Use a distinct runtime role with DML privileges and no schema ownership/DDL rights; policies/audit are insert-only through both grants and immutable-record triggers. Provision sequence access for audit IDs and SELECT on the version table. RLS, HA, disaster recovery and production role provisioning are not automated here. The initial adapter serializes metadata transactions with a PostgreSQL advisory transaction lock; it is not a multi-writer scaling design.

With -attested-only -trust-bundle roots.pem, no CA private key is needed. Obtain node/control certificates and keys from your managed issuer/SPIRE deployment, then use the attestation endpoints. Data-plane control credentials are supplied with -peer-cert and -peer-key; files are reread on new handshakes. Development issuance instead creates a short-lived control identity from the explicitly configured development CA. Nodes now reload validated credential files on new handshakes, pinning their original identity and rejecting NotBefore rollback. Publish matching files atomically and refresh membership through the managed attestation API. A live Workload API agent integration is not included.

Trusted-bundle changes require service restarts. Both old and new roots may be configured during rotation. CSR renewals are pinned to the previous certificate; managed refresh is allowed only for attested memberships, never as a bypass for superseded CSR credentials. Expired or quarantined memberships cannot refresh themselves. Certificate expiry is not a substitute for explicit quarantine.

Build and release

sh scripts/build.sh VERSION builds burst, burstnode, burstpolicy, burst-policy-worker, starburst and burstworker into dist/ and writes SHA-256 hashes to manifest.json. BURST_BUILD_DIRECTORY overrides the destination. sh scripts/generate-rpc.sh uses pinned generator modules to regenerate schemas. The external protoc compiler is also required.

sh scripts/release-check.sh intentionally blocks publication while module namespaces, local sibling replacements or licenses are unresolved. This command never creates GitHub repositories, pushes changes or selects a license. CI runs module checks and a dedicated PostgreSQL service; it has not been published or executed on GitHub yet.

Verification boundaries

The local race suite covers the original identity slice plus groups, grant/member revocation, three-node encrypted storage, a replacement node, role/network/digest/path rejection, repair, expiry/tombstones, stale policy rejection, retention non-resurrection, authority loss, managed attestation and certificate renewal. Linux Go 1.25 module checks and native TCP/TLS suites passed. The full control/data suite also passed on PostgreSQL 16 with Linux Go 1.27.3, including repeated execution and hard-worker startup regression checks. See implementation-status.md.

This is still missing relay/NAT traversal, distributed consensus, application service access and distributed scheduling, real-provider browser interoperability, browser automation, backup restoration, production deployment and independent repository publication.

See Starburst v2 for versioned context, signed modules, capability requirements, simulation and automation planning.

Built from plans/ecosystem-slice.md in the Burst Kit workspace. Check implementation status before deployment.

Search the documentation