Skip to content

Add GitHub OAuth authentication and admin authorization#89

Open
Aias wants to merge 1 commit into
mainfrom
feat/auth
Open

Add GitHub OAuth authentication and admin authorization#89
Aias wants to merge 1 commit into
mainfrom
feat/auth

Conversation

@Aias

@Aias Aias commented Feb 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds single-user GitHub OAuth authentication with HMAC-signed httpOnly session cookies
  • Gates all mutations and sensitive queries behind admin-only tRPC procedures
  • Filters private records from all public queries (records, search, media)
  • Gates vector/semantic search behind admin auth (costs OpenAI per embedding query)
  • Hides admin-only UI elements (record editing, link management, create buttons, admin filters) for non-authenticated users
  • Adds dev-only toggle in header to simulate admin vs public views without OAuth setup
  • CLI bypass (isAdmin: true) preserves existing workflow
  • When auth env vars are missing, all requests are treated as admin (backwards-compatible)

New files

  • src/server/lib/auth.ts — session cookie + auth utilities
  • src/server/lib/rate-limit.ts — IP-based rate limiter
  • src/app/components/auth-button.tsx — login/logout button + dev toggle
  • src/app/routes/api/auth/{github,callback,logout}.ts — OAuth route handlers

Test plan

  • Without auth env vars: app works identically to before (all admin)
  • Dev toggle: click Admin/Public in header to switch views, verify UI changes
  • Public view: record form hidden, relations read-only, no create/delete/merge buttons, no private filter
  • With auth env vars: OAuth flow works, session persists across page loads
  • CLI: rcr commands work without auth configuration
  • Private records hidden from public queries
  • Vector search returns UNAUTHORIZED for non-admin

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bcb13a89df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/server/api/init.ts
Comment on lines 19 to 24
where: {
id: {
in: ids as number[],
},
...(isAdmin ? {} : { isPrivate: false }),
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Prevent private linked records from leaking via loaders

When a non-admin loads a public record, the top-level isPrivate filter only guards the root record. The loader still fetches outgoingLinks.target without any isPrivate condition, so a public record that links to a private one will return that private target’s title/id to unauthenticated users. This defeats the “private records hidden from public queries” goal; you need to filter nested link targets by isPrivate (or omit them) when isAdmin is false.

Useful? React with 👍 / 👎.

Comment on lines 88 to 91
)`,
type: recordType,
...(isAdmin ? {} : { isPrivate: false }),
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid exposing private link targets in text search

The new isPrivate filter only applies to the primary search records. outgoingLinks.target is still fetched with no privacy constraint, so a non-admin search can return public records that include private linked targets (titles/ids) in the payload. This leaks private record metadata to public users whenever a public record links to a private one. Consider filtering outgoingLinks.target by isPrivate: false (or suppressing link targets) for non-admin callers.

Useful? React with 👍 / 👎.

Implement single-user auth via GitHub OAuth with HMAC-signed httpOnly
session cookies. All mutations and sensitive queries are now gated behind
admin procedures, while read-only access to the knowledge base remains
public. Private records are filtered from all public queries.

- GitHub OAuth flow (authorize, callback, logout route handlers)
- HMAC-SHA256 signed session cookies with timing-safe validation
- Admin procedures: adminProcedure, adminRateLimitedProcedure
- Privacy filtering on records, media, and search queries
- Vector search gated behind admin auth (costs OpenAI per query)
- Frontend UI gating: read-only views for non-admin users
- Dev-only toggle to simulate admin vs public without OAuth setup
- CLI bypass (isAdmin: true) preserves existing dev workflow
- Auth disabled by default when env vars are missing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant