Context
Follow-up from the retained RC3 application validation in better-stack-web#37 and the finalized server surfaces from #202.
This is a post-v3 incremental DX improvement. It must not block or reopen v3.
Friction
RC3's separation between request-authorized, trusted, and raw operations is sound, but the property names do not communicate enough at a security-sensitive call site:
myStack.forRequest(request).operations.blog.createPost(...)
myStack.trusted.blog.createPost(...)
myStack.raw.blog.createPost(...)
A developer must consult declarations/docs to remember that:
- request operations resolve identity, derive trusted facts, and enforce policy;
- trusted operations intentionally skip caller authorization but preserve validation, domain behavior, and lifecycle hooks;
- raw access bypasses more of the composition contract and is not the normal application API.
trusted does not show why bypassing authorization is justified, and raw understates the danger. Both are easy to autocomplete into ordinary application code.
Proposed better alternative
Add capability-explicit APIs in a backward-compatible minor release:
const system = myStack.asTrusted({
reason: "HMAC-verified blog generation webhook",
})
await system.operations.blog.createPost(input)
await myStack.unsafe.raw.blog.createPost(input)
Preferred shape:
- Keep
forRequest(request).operations as the authoritative caller surface.
- Add
asTrusted({ reason, actor? }).operations so bypass intent is explicit and available to logs/hooks.
- Move the low-level escape hatch under
unsafe.raw or expose unsafeRaw; the name should clearly state that composition guarantees are being bypassed.
- Retain
.trusted and .raw as deprecated aliases through the next major release.
- Put the exact guarantees on every surface in generated JSDoc/hover text and link to one capability matrix.
- Brand trusted/raw capabilities as server-only so they cannot enter the browser-safe projection.
The reason should be lightweight application context, not an authorization mechanism. It improves reviewability and optional audit logging without pretending to make a trusted call safe by itself.
Acceptance criteria
Relationship to existing docs work
#175 should document the RC3 surfaces. This issue improves the interface itself so the trust decision remains clear during autocomplete and code review after those docs are no longer in view.
Release boundary
Post-v3 enhancement only. Do not hold v3 publication or require an RC4 for this issue.
Context
Follow-up from the retained RC3 application validation in better-stack-web#37 and the finalized server surfaces from #202.
This is a post-v3 incremental DX improvement. It must not block or reopen v3.
Friction
RC3's separation between request-authorized, trusted, and raw operations is sound, but the property names do not communicate enough at a security-sensitive call site:
A developer must consult declarations/docs to remember that:
trusteddoes not show why bypassing authorization is justified, andrawunderstates the danger. Both are easy to autocomplete into ordinary application code.Proposed better alternative
Add capability-explicit APIs in a backward-compatible minor release:
Preferred shape:
forRequest(request).operationsas the authoritative caller surface.asTrusted({ reason, actor? }).operationsso bypass intent is explicit and available to logs/hooks.unsafe.rawor exposeunsafeRaw; the name should clearly state that composition guarantees are being bypassed..trustedand.rawas deprecated aliases through the next major release.The
reasonshould be lightweight application context, not an authorization mechanism. It improves reviewability and optional audit logging without pretending to make a trusted call safe by itself.Acceptance criteria
.trustedand.rawconsumers remain source-compatible with deprecation guidance.Relationship to existing docs work
#175 should document the RC3 surfaces. This issue improves the interface itself so the trust decision remains clear during autocomplete and code review after those docs are no longer in view.
Release boundary
Post-v3 enhancement only. Do not hold v3 publication or require an RC4 for this issue.