Scope access to a workspace
Authenticate in your app and check ownership before session access or source reads.
Continue from chat. Cereal trusts your server's asserted identity; it does not authenticate the person using your application.
Derive identity from authentication
The starter maps HTTP Basic credentials to Ada and Grace, each with a separate workspace. Neither a form field nor a model argument chooses the session owner or workspace.
function authenticate(request: Request): Member | undefined {
const header = request.headers.get("authorization") || ""
if (!header.startsWith("Basic ")) return undefined
const credentials = Buffer.from(header.slice(6), "base64").toString()
return members.find(({ id, password }) => {
const expected = Buffer.from(`${id}:${password}`)
const actual = Buffer.from(credentials)
return expected.length === actual.length && timingSafeEqual(expected, actual)
})
}
async function ownsSession(id: string, member: Member) {
const session = await client.sessions.get({ id })
return (
session.identity?.id === member.id && session.metadata?.workspaceId === member.workspaceId
)
}Every token, message, pending-approval, and decision request checks ownsSession before
calling Cereal. A session belonging to another member returns 404. State-changing browser
requests also require an Origin matching your application.
The source tools separately check workspaceId in verified session metadata. Search filters
before returning titles; reading by ID checks the same boundary. Knowing a document ID does
not grant access to its contents.
Test two workspaces
- As
ada, ask about the Orion launch and copy the session ID from browser storage or the console. - Open a private browser window and sign in as
grace. - Ask to read
launch-plan. The tool returnsfound: false. Grace can readprivate-roadmap, the Atlas document. - In Grace's window, request
/api/sessions/ADA_SESSION_ID/token. The app returns 404. - Confirm message and decision routes enforce the same ownership check.
Replace the fixture credential mapping with your application's sign-in and workspace membership lookup. Keep server-derived identity and ownership checks on every route. See identity and metadata.
Continue to recover and debug, or optionally control publication with a hook.