Documentation Contributor guides

Your account + your data

The contributor-side reference for what Steward stores about you, how to control it, and how to delete it. Covers leave windows, private-repo scanning consent, Bring Your Own Key (BYOK) for the per-PR Large Language Model (LLM), and the full account-deletion flow.

This is the privacy-oriented companion to Contributing to a Steward repo — that doc covers what Steward sees on a PR; this doc covers what's stored server-side and how to manage it.

Where to find everything

The account surface lives at:

/app/account

It groups by concern:

Section What it controls
Identity Display name, profile visibility.
Privacy Private-repo scanning consent.
API tokens Mint / revoke personal access tokens.
BYOK Anthropic API key for the per-PR LLM scoring.
Leave window Pause reputation decay for an absence period.
Delete account The tombstone flow.

Sign in via GitHub OAuth on the first visit — the account page is gated by a real session.

Contributor reports at /app/me/contributions can include your contributions from private repos in addition to public ones. Off by default — opt in explicitly via the Privacy section.

When you grant:

  • A user.private_repo_consent_granted audit event lands with your app.users.private_repo_scan_consented_at set to the current timestamp (or preserved if already granted).
  • Subsequent contributor-report generations with include_private_repos=true are allowed.
  • Your existing GitHub installation grants don't change — the consent is the Steward-side gate; the OAuth scope is the GitHub-side gate.

When you revoke:

  • user.private_repo_consent_revoked audit event lands.
  • private_repo_scan_consented_at is cleared.
  • Subsequent GenerateReport(include_private_repos=true) calls refuse with FAILED_PRECONDITION until you re-grant.

Re-granting after revocation does not restore the original consent timestamp; a fresh now() lands. The audit log preserves the full grant/revoke history.

Leave windows — pause reputation decay

If you're going dark for a while (sabbatical, parental leave, extended PTO, switching focus to another project), set a leave window from the account page. The window pauses reputation decay for the period [from, leave_until].

The leave window:

  • Applies to every domain in every repo simultaneously. It's per-user, not per-repo.
  • Has no minimum — set it for two weeks if you want.
  • Has no maximum — but the decay-resumes-when-you-return property means you don't need to "renew" it. Just extend the end date if your leave runs longer.
  • Doesn't hide you. Your reputation is still queryable; it's just frozen at its pre-leave value rather than decaying down.

Set this when you're going dark for more than a month or two. For a one-week vacation, the decay impact is negligible (less than 1% at a 180-day half-life).

API tokens

If you're integrating with Steward from CI, a script, or another machine identity, mint a personal access token from the API tokens section. Reference: /docs/api.

A few contributor-relevant properties:

  • Plaintext is shown once. Copy it on the mint page; the server stores only a SHA-256 hash.
  • Tokens carry scopes. Read-only scopes for the four shipped RPCs. Choose narrowly.
  • First-use-per-hour audit event. The api_token.used event is dedup'd so a CI call-once-per-minute integration doesn't drown your audit log; you'll see the first call per hour per token.
  • Revoke immediately if compromised. The token list shows every active token; the Revoke button takes effect on the next API call (within seconds).
  • Tokens cascade-revoke on account deletion. No manual cleanup needed if you nuke the account.

Bring Your Own Key (BYOK)

You can point the per-PR LLM scoring at your own Anthropic account so its costs flow through your provider's billing instead of the repo's tier credits. From the BYOK section:

  • Add your Anthropic API key. Stored encrypted at rest (AES-256-GCM with a separate envelope key — the value lives in app.byok_secrets).
  • Toggle BYOK on for repos you maintain. The toggle is per repo — you can't force BYOK onto someone else's repo.
  • Revoke any time; the per-PR worker falls back to the repo's tier-credit path.

Privacy-relevant: a BYOK key is always personal — never shared across an org even if you're a member of one. The SpiceDB schema's byok_secret definition has only a parent_user relation; no org cascade exists.

If you don't enable BYOK, nothing about your interaction with Steward changes — the repo's credit-tier path runs the LLM calls as usual.

Delete your account

The tombstone flow lives at Delete my account on the account page. The user-facing flow:

  1. Click Delete my account.
  2. Read the pre-flight check. Steward runs a read-only check (CheckAccountDeletion) for blockers — rows you own that other parties depend on (active Contributor License Agreement (CLA) corporate signatory for an active corporate CLA, etc.). If blockers exist, you'll see precise resolve-this-first guidance before the modal opens.
  3. Type the exact phrase delete my account into the confirmation field. No other phrase works; this is the guard against accidental clicks.
  4. Click Permanently delete. The server runs the tombstone transaction.

You'll get a confirmation showing the counts:

Account deleted.
  Sessions deleted:        4
  BYOK secrets deleted:    1
  CLA signatures deleted:  3
  Relationships deleted:   12

And a security email to your registered address.

What the tombstone does

The flow runs in a single Postgres transaction:

Step Action
1 List your SpiceDB subject tuples (auth.relationships rows where you're the subject), FOR UPDATE so a concurrent grant can't race.
2 DualWrite-delete those tuples (Postgres mirror + SpiceDB), so every role grant you held is revoked atomically.
3 Hard-delete sessions, BYOK secrets, individual CLA signatures. The counts above come from these steps.
4 Tombstone app.users — scrub identity-bearing columns (login, email, avatar) and replace them with a sentinel. The row itself stays so foreign-key references continue to resolve.

Then commit. After commit:

  • user.account_deleted audit event is recorded with the cleanup counts + your pre-tombstone github_login for forensic recoverability.
  • A security email fires to your registered email address.
  • Your session cookie is cleared.

What persists after deletion

The tombstone scrubs identity data. It does not delete:

  • Your PR_MERGED events. These are load-bearing for reputation math in repos you contributed to — removing them would silently change other contributors' relative reputations. The events stay; their contributor_id points at your tombstoned row.
  • Your historical cla.signed audit events. They're the legal record of "you agreed to v1 at time T." Steward doesn't tamper with the historical attestation.
  • Audit events you were the actor on. They continue to point at the tombstoned app.users row; readers see the pre-tombstone github_login value from the event metadata, but the app.users row no longer carries your identity.

If you object to the events themselves persisting, your recourse is the maintainer of each repo you contributed to — they own their repo's data, including your contributions. Steward doesn't unilaterally delete events that affect others.

What you can't delete this way

  • Corporate CLA signatures you signed as the signatory (i.e., signed on behalf of your company). Those represent the corporation's agreement, not yours individually; you can't unilaterally invalidate a contract your employer needs.
  • Audit events on repos you don't own. As above.
  • Your impersonated session's deletion — if a staff member is impersonating you, account deletion is refused with FAILED_PRECONDITION. End the impersonation first (which the impersonation banner makes clear).

Pre-flight blockers — what you'll see

Common blockers and how to resolve:

Blocker Action
You're the active signatory on a corporate CLA with covered employees Transfer the signatory role to a colleague at the corporation first, then retry.
You're the sole member_manager on an org Grant member_manager to someone else on that org first (see Org membership).
An active subscription is in your name Cancel the subscription via the Paddle portal first, then retry after the period ends.

The CheckAccountDeletion response surfaces precise per-source counts so you know exactly what to fix.

Privacy quick-reference

A summary of what's stored where + how to control it:

Data Where How to control
GitHub login + email + avatar app.users Tombstoned by account deletion.
Per-domain reputation Replayed from ledger_events Decays naturally; pauses during leave window; preserved post-deletion.
CLA signatures app.cla_signatures Individual: delete from /app/cla. Corporate: contact the corporate signatory.
BYOK API key app.byok_secrets Revoke from /app/account → BYOK. Deleted on account deletion.
API tokens app.api_tokens Revoke individually; cascade-revoked on account deletion.
Sessions app.sessions Sign out clears the current session. Account deletion clears all sessions.
Audit events app.audit_events Append-only by design. Cannot be deleted; tombstoning scrubs identity but preserves events.
Private-repo scan consent app.users.private_repo_scan_consented_at Grant/revoke from /app/account → Privacy.

What's next