Skip to content

[codex] harden env broker and adaptive log RLS#139

Merged
besfeng23 merged 1 commit into
mainfrom
codex/audit-env-rls-hardening
Jul 4, 2026
Merged

[codex] harden env broker and adaptive log RLS#139
besfeng23 merged 1 commit into
mainfrom
codex/audit-env-rls-hardening

Conversation

@besfeng23

@besfeng23 besfeng23 commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

This PR applies the first audit-fix batch for the Pandora Memory Engine:

  • Restricts Env Broker admin authorization to either a valid internal operator token or Supabase app_metadata env-admin capability.
  • Gates /admin/env before rendering drift/provider status, while keeping the operator unlock token server-only in an HttpOnly, Secure, SameSite=strict cookie.
  • Adds owner-scoped RLS policies for adaptive memory log tables.
  • Removes the brittle unit-test dependency on a global npm binary.
  • Fixes the well-known OAuth route config re-export warning.
  • Adds a narrow npm override for patched postcss to clear the current audit advisory.

Validation

  • npm run typecheck passed.
  • npm run lint passed with 2 existing warnings: lib/db/core-repositories.ts unused PublicTableInsert, and anonymous default export in vitest.config.ts.
  • npm run test passed: 99 files, 637 tests.
  • npm run build passed.
  • npm run env:policy passed for 89 discovered env keys.
  • npm audit --json passed with 0 vulnerabilities.
  • git diff --check passed.
  • Production-mode local route smoke passed against next start: signed-out /admin/env shows locked copy and hides drift data; operator unlock returns 303 and sets a root-path HttpOnly/Secure/SameSite=strict cookie; authorized /admin/env shows the console and does not echo the operator token.
  • Remote checks passed: GitHub Actions CI, Vercel, and CodeRabbit.
  • supabase db lint --local --fail-on none could not run because no local Postgres/Supabase database was available.

Rollout Notes

  • No production jobs were run.
  • No dryRun:false execution was run.
  • No secret files were read.
  • This does not enable retrieval, embeddings, GPT Actions, MCP, public memory reads, public persistence, scoring execution, pruning, or protected production jobs.
  • The Supabase migration still needs to be applied to the intended target database and verified through pg_policies/schema inspection before claiming it is deployed.

Summary by CodeRabbit

  • New Features

    • Admin environment access now shows a locked state with unlock instructions when access is restricted.
    • OAuth authorization server routes now use consistent dynamic Node.js rendering.
  • Bug Fixes

    • Improved admin access checks so only authorized sessions or valid operator unlocks can reach sensitive broker actions.
    • Broadened the unlock cookie scope so admin access works reliably across the app.
    • Added stricter data access rules for memory logs to better protect user-owned records.

@vercel

vercel Bot commented Jul 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
memory Ready Ready Preview, Comment Jul 4, 2026 11:24am

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8c7e2e53-f4b8-48a7-a186-05b993aefb35

📥 Commits

Reviewing files that changed from the base of the PR and between d301813 and 79a9241.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • app/.well-known/oauth-authorization-server/[...resource]/route.ts
  • app/admin/env/page.tsx
  • app/api/admin/env/status/route.ts
  • lib/services/env-admin-route-guard.ts
  • package.json
  • scripts/verify-first-reviewed-memory-fixture.ts
  • supabase/migrations/20260704103859_adaptive_log_rls_policies.sql
  • tests/unit/env-admin-route-guard.test.ts
  • tests/unit/first-reviewed-memory-fixture.test.tsx
  • tests/unit/rls-policies.test.ts

📝 Walkthrough

Walkthrough

Changes span env-admin authorization (operator-token-first flow, capability checks, locked admin UI, cookie path widening, tests), a new Supabase RLS migration for two log tables with matching tests, an OAuth route export adjustment, a fixture-verification CLI refactor, and a postcss version override in package.json.

Changes

Env Admin Guard and UI

Layer / File(s) Summary
Env-admin capability checks and guard control flow
lib/services/env-admin-route-guard.ts
requireEnvAdmin tries operator-token auth first, then requireApiUser with 401/403 responses; new hasEnvAdminCapability checks app_metadata roles/capabilities.
Unlock cookie path widening
app/api/admin/env/status/route.ts
Widens the unlock cookie's path from /api/admin/env to /.
Locked env broker page and unlock form
app/admin/env/page.tsx
Gates the admin page behind requireEnvAdmin(false), renders LockedEnvBrokerPage with an unlock form when locked, adds dynamic = "force-dynamic", and updates unlock helper text.
Guard and unlock flow unit tests
tests/unit/env-admin-route-guard.test.ts
Adds mocks and tests for capability checks, operator token bypass, and unlock cookie attributes.

Adaptive Log RLS Policies

Layer / File(s) Summary
RLS migration and policy definitions
supabase/migrations/20260704103859_adaptive_log_rls_policies.sql, tests/unit/rls-policies.test.ts
Enables/forces RLS and adds idempotent owner-scoped SELECT/INSERT policies on memory_retrieval_logs and memory_model_call_logs; tests assert policy presence.

Miscellaneous: OAuth route export, fixture CLI, postcss override

Layer / File(s) Summary
OAuth authorization server route exports
app/.well-known/oauth-authorization-server/[...resource]/route.ts
Locally defines dynamic/runtime instead of re-exporting them; re-exports only GET/OPTIONS.
Fixture verification CLI refactor
scripts/verify-first-reviewed-memory-fixture.ts, tests/unit/first-reviewed-memory-fixture.test.tsx
Extracts runFirstReviewedMemoryFixtureCli returning {ok, output}; test invokes it directly instead of spawning npm.
postcss version override
package.json
Adds top-level overrides pinning postcss to ^8.5.16.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AdminEnvPage
  participant EnvAdminGuard
  participant StatusRoute

  Client->>AdminEnvPage: Request /admin/env
  AdminEnvPage->>EnvAdminGuard: requireEnvAdmin(false)
  EnvAdminGuard->>EnvAdminGuard: Check operator token
  alt operator token valid
    EnvAdminGuard-->>AdminEnvPage: {user, response: null}
  else no operator token
    EnvAdminGuard->>EnvAdminGuard: requireApiUser + hasEnvAdminCapability
    alt unauthenticated
      EnvAdminGuard-->>AdminEnvPage: 401 response
    else lacks capability
      EnvAdminGuard-->>AdminEnvPage: 403 response
    else authorized
      EnvAdminGuard-->>AdminEnvPage: {user, response: null}
    end
  end
  alt guard.response present
    AdminEnvPage-->>Client: Render LockedEnvBrokerPage
    Client->>StatusRoute: POST operator_key
    StatusRoute-->>Client: Set-Cookie pandora_env_admin (path=/)
  else
    AdminEnvPage-->>Client: Render full broker dashboard
  end
Loading

Possibly related PRs

  • besfeng23/Memory#75: Modifies the same fixture verification CLI script and its unit test that this PR refactors.

Suggested labels: codex

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/audit-env-rls-hardening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@besfeng23 besfeng23 marked this pull request as ready for review July 4, 2026 11:40
@besfeng23 besfeng23 merged commit e90f3ed into main Jul 4, 2026
4 of 5 checks passed

@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: 79a9241e66

ℹ️ 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".

on public.memory_retrieval_logs
for insert
to authenticated
with check ((select auth.uid()) = user_id);

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 Constrain adaptive log inserts to valid namespaces

This new authenticated insert policy only checks ownership, so any signed-in user can now insert memory_retrieval_logs rows for their own user_id with namespace = 'foo' or another cross-domain value; the same pattern is repeated for memory_model_call_logs below. Since these tables feed adaptive memory/retrieval audit data and the project requires strict real_life/au separation, the RLS with check should also enforce the allowed namespace before opening authenticated writes.

Useful? React with 👍 / 👎.


const response = NextResponse.redirect(new URL("/admin/env", request.url), { status: 303 });
response.cookies.set({ name: ENV_ADMIN_COOKIE_NAME, value: candidate, httpOnly: true, sameSite: "strict", secure: true, path: "/api/admin/env", maxAge: 60 * 30 });
response.cookies.set({ name: ENV_ADMIN_COOKIE_NAME, value: candidate, httpOnly: true, sameSite: "strict", secure: true, path: "/", maxAge: 60 * 30 });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope the operator-token cookie to env admin routes

After a successful unlock, this stores the raw operator/job token as a Path=/ cookie, so every subsequent request to unrelated routes such as /dashboard carries pandora_env_admin even though only /admin/env and /api/admin/env/* need it. Because getConfiguredOperatorTokens() accepts internal production tokens, this broadens where a secret is exposed inside the app; use a route-scoped/opaque unlock cookie instead of sending the raw credential site-wide.

Useful? React with 👍 / 👎.

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.

2 participants