Skip to content

[Feature]: Google / OIDC sign-in for the admin #285

Description

@ryantthomas

Problem

The admin only supports email + password sign-in. That's fine for single-author sites, but awkward for the multi-author Postgres use case in the README — every author would need a separate Instatic password on top of their existing Google login.

It also adds weight to password reset (#166), still open. Users signing in with Google wouldn't need that fix at all.

There's OAuth in the codebase already (#122, #245, server/ai/mcp/oauth/), but it's outbound — Instatic talking to AI providers, or acting as an auth server for MCP clients. This would be the reverse: Instatic accepting Google sign-in.

Proposed solution

Smallest useful version: Google sign-in as an additional login method, not a replacement. Password login stays exactly as it is.

  1. Existing user links a Google account from Account → Security.
  2. Login form gets a "Sign in with Google" button for users who've linked one.
  3. No auto-provisioning — an unrecognized Google account is rejected, not auto-created.

Two questions I'd want your call on before writing code:

  1. Where the identity lives — a separate user_identities table (user_id, provider, subject, linked_at), or a sentinel value in password_hash? I'd lean toward the separate table since it's additive on both dialects and leaves users untouched.
  2. Secret storage — reuse masterKey.ts (same path as TOTP seeds) instead of a bare env var?

Alternatives considered

Auth proxy in front (Caddy forward_auth + oauth2-proxy/Authelia) — works today, no code needed, probably worth documenting regardless. But it authenticates at the edge with no notion of which Instatic user is signed in, so it can't drive per-author capabilities or the audit log — and it doesn't help the Railway one-click path.

Do nothing, just document the proxy route — reasonable if SSO isn't a direction you want core to go. Auth isn't on the README roadmap, so wanted to ask rather than assume.

Happy to build whichever direction makes sense - just didn't want to start guessing at auth design without your input!

Area

Other (auth / access)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions