How we handle your code,
your tokens, and your data.
Story Refiner connects to your repos, clones them into an isolated workspace, and runs a grounded refinement agent against them. The agent has read access. It does not write. Below is exactly how that works, what we’re defending against, and where the limits are.
Last updated 2026-05-01. We update this page when the architecture changes.
Defaults, at a glance
GitHub OAuth scopes are read:user,repo. The agent cannot push commits, open PRs, or modify your repo.
OAuth tokens are AES-256-GCM encrypted in our database. The browser cookie only holds a session id.
Every domain query is scoped to your org id at the type level. No helper exists that can return another tenant’s data.
Each chat session gets its own filesystem-isolated clone. Sessions cannot read each other’s files.
Tokens, OAuth scopes, and what we ask for
When you sign in with GitHub, Story Refiner requests the minimum scopes required to read the repos you choose to connect. Microsoft / Azure DevOps follows the same pattern via Microsoft Entra ID.
| Provider | Scope requested | Why we need it |
|---|---|---|
| GitHub | read:user, repo | Identify you and clone the specific repos you connect. Not used to write. |
| Azure DevOps | vso.code, vso.work | Read code repositories and existing work items for grounding context. |
We never request write:repo, delete_repo, or any organization-admin scope. If
a future feature needed a broader scope, you would re-authorize explicitly.
How your tokens are stored
- OAuth tokens are encrypted with AES-256-GCM before being written to Postgres. The encryption key lives in an environment secret, never in the database.
- The session cookie (
sid) only holds a session id. The OAuth token is never exposed to the browser, never returned in JSON, never logged. - When the agent clones a repo, the token is embedded in the clone URL only for the duration
of the
git clone, then scrubbed from any error output before any error surfaces in our logs or your chat. - You can revoke our access at any time at github.com/settings/applications. Revocation invalidates all subsequent agent runs for your org immediately.
Tenant isolation
Every domain table in our database has org_id as the first component of its primary key. All database access flows through a single gateway in src/lib/server/db/scoped.ts that takes orgId as a required argument. There is no helper that
can omit it — a query that would leak across tenants does not compile.
The orgId used for every query is sourced
exclusively from the authenticated session, never from a request body, query string, or cookie
payload. The agent runtime itself uses a per-session gitHubToken passed via the Copilot SDK’s documented multi-tenant pattern, so two users’ agent sessions
never share an identity.
The per-chat workspace
When you start a chat session, Story Refiner clones the selected repos into a fresh directory
under os.tmpdir()/story-refiner/<chat_session_id>/ and runs the agent there as a CLI subprocess with that directory as its working dir. The agent cannot
read files outside its working directory; it cannot see other users’ workspaces, your environment
secrets, or anything else on the host.
Sessions are short-lived. Workspaces are destroyed at the end of the session.
Threat model — what we defend against
Defense: The forOrg(orgId) chokepoint described above. No code
path exists that returns another tenant’s data, intentionally or by mistake.
Defense: Tokens are encrypted at rest, never returned to the browser,
scrubbed from logs and error output, and tied to a session that you can revoke at any
time. The recent CVE wave on AI coding agents (Codex, Claude Code, Copilot SWE Agent in
2025–2026) was instructive: most of those attacks turned on tokens being available
in the agent’s environment with broader scope than needed. We use the smallest scope
and don’t put tokens on PATH or in process env.
Defense: The agent has no tools that can write to your repo, open PRs, or trigger CI. Even if a malicious file in a cloned repo successfully injected into the agent, the worst-case action is the agent saying something it shouldn’t. There is no path from prompt injection to credential exfiltration or repo modification. Limit: The agent can still summarize content from a malicious file back to you in the chat — the same way reading any untrusted input would. We treat repo content as untrusted; you should treat agent output as untrusted too.
Defense: Cloned repos are read, not executed. We do not run npm install, pip install, or any other dependency
resolution against your code. The agent reads files; it does not execute them.
Defense: Session cookies are HttpOnly, Secure, and SameSite=Lax. Sessions expire on a bounded
TTL; revoking the OAuth grant invalidates all server-side sessions tied to that grant.
What we explicitly don’t do
- We do not train any model on your code, your tickets, or your conversations.
- We do not write to your repository. No commits, no PRs, no branch creation.
- We do not share, sell, or expose your data to other tenants. Ever.
- We do not request scopes we don’t use. If you see a scope on the consent screen that isn’t in the table above, that’s a bug — tell us.
Compliance & roadmap
We’re early. Here’s the truth about where we are:
- SOC 2 Type II: in progress. Type I report available under NDA on request once issued.
- Data residency: EU and US tenants on launch. Customer-chosen residency is on the Enterprise tier.
- External pen-test: scheduled for Q3. Summary will be linked here when complete.
- HIPAA / GDPR / DPA: Standard EU SCC and a DPA are available to all paid tenants on request.
Reporting a security issue
If you’ve found a vulnerability, email [email protected] with the subject line "Security disclosure". We acknowledge within one business day. We don’t have a paid bounty program yet, but we publicly credit researchers (with permission) for any valid report and we treat responsibly disclosed issues with priority.
Questions your security team would ask?
Send them a link to this page. Or sign in and try the agent yourself — read-only, no commitment.
Get early access