Authentication — protect the web UI and API

Open
#2 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet
Tech stack
go, sql

Research direction

Start with sub-issue #16, the stated foundation, then review the proposed accounts, account_identities, account_passwords, and sessions schema. Trace the listed web UI and API routes, and use the account-linking rules and provider sub-issues (#17 and #18) to define the remaining work. The umbrella issue is done when its listed authentication coverage is complete.

Written by the indexing model from the issue text.

Description

enhancement security

SentinelSnap currently has no authentication. Anyone who can reach the server can view all snaps, delete them, and rename them.

This is the umbrella issue tracking the full auth implementation. Each method is a separate sub-issue so they can be worked on independently.

Sub-issues

  • #16 Email / password login (foundation — implement this first)
  • #17 Google SSO (OAuth2 / OIDC)
  • #18 Sign in with Apple (OIDC)

Design decision: federated identity (multiple providers → one account)

All providers resolve to the same account. A user can sign in with their password one day and Google the next — it's the same account. This is the standard model and the correct choice here.

Schema
accounts
  id          BIGSERIAL PRIMARY KEY
  email       TEXT NOT NULL UNIQUE
  created_at  TIMESTAMPTZ DEFAULT now()

account_identities
  id           BIGSERIAL PRIMARY KEY
  account_id   BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE
  provider     TEXT NOT NULL        -- 'password', 'google', 'apple'
  provider_uid TEXT NOT NULL        -- provider's user ID (or account_id for password)
  email        TEXT                 -- email reported by provider at link time
  created_at   TIMESTAMPTZ DEFAULT now()
  UNIQUE (provider, provider_uid)

-- password credentials stored separately, not in accounts
account_passwords
  account_id    BIGINT PRIMARY KEY REFERENCES accounts(id) ON DELETE CASCADE
  password_hash TEXT NOT NULL       -- bcrypt
  updated_at    TIMESTAMPTZ DEFAULT now()
Account linking rules

Never auto-link by email alone. This is the critical security rule.

The email auto-link attack: an attacker creates a Google account with your email → server sees the same email → auto-links → attacker is in.

Safe linking flow:

  1. First login with a provider — if no account_identities row exists for (provider, provider_uid), create a new account and link it.
  2. Subsequent login with the same provider — look up by (provider, provider_uid), sign in.
  3. Linking a second provider to an existing account — only allowed while already authenticated (via "Connect Google" in account settings). Never automatic.

This means two accounts with the same email but different providers are distinct until the user explicitly merges them. That is the safe default.

Session mechanism

Standard server-side sessions via a sessions table (or signed cookies). All login methods produce the same session type — no provider-specific session logic leaks into the rest of the app.

What this covers once complete

  • Web UI protected behind a login page.
  • GET /snaps, PATCH /snaps/{id}, DELETE /snaps/{id}, GET /events require a valid session.
  • POST /snaps uses API key auth (#4) — phone shortcuts are not affected.
  • GET /photos/{token} — token acts as access proof; decide whether additional session auth is needed.

Implementation note

Consider Ory Kratos to handle the federated identity and linking flows correctly out of the box, rather than implementing account linking logic from scratch.

Related

  • #3 Authorization (roles — implement after this)
  • #4 API keys for snap submission
Dominant language
Go
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from williamokano/SentinelSnap

All issues in williamokano/SentinelSnap

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.