Skip to content

feat: warn on startup when auth is enabled but no IAM rules exist#22

Merged
tianzhou merged 1 commit into
mainfrom
remove-pricing
Jun 25, 2026
Merged

feat: warn on startup when auth is enabled but no IAM rules exist#22
tianzhou merged 1 commit into
mainfrom
remove-pricing

Conversation

@tianzhou

@tianzhou tianzhou commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Pricing/licensing removal already landed in main via #21, which made IAM opt-in. This PR adds the startup-warning follow-up that the review on the original pricing change asked for.

With no [[iam]] rules configured, every authenticated principal (users and agents) gets full access to all connections. This adds a startup console.warn so an empty [[iam]] section combined with auth enabled isn't a silent misconfiguration.

⚠ Auth is enabled but no [[iam]] rules are configured — every authenticated
  user and agent has full access to all connections. Add [[iam]] rules to restrict access.

Notes

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 25, 2026 09:54
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
pgconsole Ready Ready Preview, Comment Jun 25, 2026 10:20am

@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown

Greptile Summary

This PR removes all pricing, licensing, and subscription logic from pgconsole, making every previously gated feature freely available. It scrubs the Stripe worker/webhook, deletes src/lib/plan.ts and server/lib/license.ts, and wires up the simplified config and IAM paths throughout the server, client, and test suite.

  • IAM semantics changed: the old code short-circuited to full access on FREE plan (even when [[iam]] rules existed), and returned an empty permission set on TEAM/ENTERPRISE when no rules were configured. The new code is "opt-in": no [[iam]] rules → full access; first rule → enforcement begins. This is a cleaner contract and is well-tested.
  • Features always active: audit logging, groups, banner/branding, and SSO providers are now unconditionally enabled — plan-gate calls removed consistently across audit.ts, config.ts, iam.ts, and auth-routes.ts.

Confidence Score: 4/5

Safe to merge — the plan/license removal is thorough and internally consistent, with no dangling imports or broken references across all 44 changed files.

The cleanup is complete and correct: every call-site that checked a plan gate has been removed, the new opt-in IAM contract is well-tested, and audit/groups/SSO now work unconditionally as intended. The only gap is a removed direct unit test for the delegated-agent connection cap in tests/mcp.test.ts; the invariant is still enforced in code and partially covered via dispatchTool, but the dedicated test is gone and could leave a blind spot for future refactors of iam.ts.

tests/mcp.test.ts — the 'delegated connection cap blocks other connections' test was removed; worth restoring to keep direct coverage of the agent connection isolation boundary in getAgentPermissions.

Important Files Changed

Filename Overview
server/lib/iam.ts Replaces plan-gate short-circuit with rules.length === 0 opt-in check; logic is correct, delegated-agent connection cap preserved.
server/lib/config.ts Strips license parsing, plan resolution, and user-seat validation; default config and loadedConfig assignment simplified cleanly.
tests/mcp.test.ts Removed 'delegated connection cap blocks other connections' unit test; behavior is still exercised indirectly via the dispatchTool 'fails closed on an inaccessible connection' case.
server/auth-routes.ts SSO plan-gate middleware removed; providers endpoint simplified to return all configured providers unconditionally.
server/index.ts Setting endpoint now returns banner/branding directly without feature-gating; license expiry warning and plan log removed from startup.
src/App.tsx SubscriptionModalProvider wrapper and LicenseExpiryBanner removed; indentation fixed cleanly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Request arrives] --> B{Auth enabled?}
    B -- No --> C[Full access]
    B -- Yes --> D{Any iam rules defined?}
    D -- No --> C
    D -- Yes --> E[Evaluate rules for principal + connection]
    E --> F{Any rule matches?}
    F -- Yes --> G[Union matched permissions]
    F -- No --> H[Empty set - access denied]
    G --> I[Return permission set]

    subgraph delegated ["Delegated agent extra checks"]
        J{agent.connections set?} -- Yes not matching --> K[Return empty set]
        J -- No or matching --> L[getUserPermissions for onBehalfOf user]
        L --> M{agent.permissions cap?}
        M -- Yes --> N[Intersect with cap]
        M -- No --> O[Return base user perms]
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Request arrives] --> B{Auth enabled?}
    B -- No --> C[Full access]
    B -- Yes --> D{Any iam rules defined?}
    D -- No --> C
    D -- Yes --> E[Evaluate rules for principal + connection]
    E --> F{Any rule matches?}
    F -- Yes --> G[Union matched permissions]
    F -- No --> H[Empty set - access denied]
    G --> I[Return permission set]

    subgraph delegated ["Delegated agent extra checks"]
        J{agent.connections set?} -- Yes not matching --> K[Return empty set]
        J -- No or matching --> L[getUserPermissions for onBehalfOf user]
        L --> M{agent.permissions cap?}
        M -- Yes --> N[Intersect with cap]
        M -- No --> O[Return base user perms]
    end
Loading

Comments Outside Diff (1)

  1. tests/mcp.test.ts, line 129-153 (link)

    P2 Removed unit test for delegated-agent connection cap

    The test 'delegated connection cap blocks other connections' was deleted from this block, but the behavior it verified — that a delegated agent with connections = ["prod"] returns new Set() for any other connection — is still correct in the code (line 125-127 of iam.ts) and would still pass today. The scenario is partially re-covered through the higher-level 'fails closed on an inaccessible connection' dispatchTool case, but the direct getAgentPermissions unit test is gone. If iam.ts is ever refactored, a regression in this security boundary could slip through without a low-level catch.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "Potential fix for pull request finding" | Re-trigger Greptile

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR removes all pricing/licensing/subscription mechanics from pgconsole so every feature is available without a paid plan, and cleans up the related infrastructure, UI, tests, and documentation.

Changes:

  • Deletes the plan/license model (including license verification, seat limits, gated UI, and settings fields) and updates server/client code paths accordingly.
  • Removes the Stripe webhook Cloudflare Worker and its GitHub Actions deploy workflow.
  • Removes the marketing site’s pricing page/components and updates docs to reflect “all features free” plus the new IAM “opt-in” semantics.

Reviewed changes

Copilot reviewed 43 out of 44 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
worker/stripe-webhook/wrangler.toml Removes Cloudflare Worker configuration (worker deleted).
worker/stripe-webhook/src/index.js Removes Stripe webhook handling + license email generation logic (worker deleted).
worker/stripe-webhook/package.json Removes worker package manifest (worker deleted).
worker/stripe-webhook/package-lock.json Removes worker dependency lockfile (worker deleted).
website/src/components/shared/navbar.tsx Drops the “Pricing” navbar link.
website/src/components/sections/pricing-single-tier-two-column.tsx Removes pricing UI component.
website/src/components/sections/pricing-multi-tier.tsx Removes multi-tier pricing UI component.
website/src/components/sections/pricing-hero-multi-tier.tsx Removes pricing hero + plan card UI component.
website/src/components/sections/plan-comparison-table.tsx Removes plan comparison table UI component.
website/src/app/sitemap.ts Removes /pricing from sitemap.
website/src/app/pricing/page.tsx Removes the /pricing page.
tests/plan.test.ts Removes tests for plan feature gating (plan system removed).
tests/mcp.test.ts Updates MCP/IAM test assumptions and removes a now-redundant delegated cap test.
tests/license.test.ts Removes license verification tests (license system removed).
tests/iam.test.ts Updates IAM tests to match IAM “opt-in” behavior (no rules => full access).
src/lib/plan.ts Removes plan tiers + feature gating helpers.
src/lib/auth-client.ts Removes requiredPlan from auth provider shape.
src/hooks/useSubscriptionModal.ts Removes subscription modal context hook.
src/hooks/useSetting.ts Removes plan/license fields from settings response and hook.
src/components/SubscriptionModal.tsx Removes the subscription/upgrade modal UI.
src/components/LicenseExpiryBanner.tsx Removes license expiry banner UI.
src/components/Header.tsx Removes “Subscription” menu item and related imports.
src/components/AuthForm.tsx Removes client-side SSO plan gating UI/disable behavior.
src/App.tsx Removes subscription provider + license banner wiring from the app shell.
server/lib/license.ts Removes license JWT verification and result model.
server/lib/iam.ts Removes plan-based IAM gating; IAM is now opt-in based on presence of rules.
server/lib/config.ts Removes general.license, plan resolution, and seat-limit validation; groups are no longer plan-gated.
server/lib/audit.ts Removes plan gating so audit logs always emit.
server/index.ts Removes plan/license fields from /api/setting and removes license status logging.
server/auth-routes.ts Removes plan gating on OAuth routes/providers; providers are always advertised if configured.
pgconsole.example.toml Scrubs example license key and plan-gated branding wording.
docs/getting-started/faq.mdx Updates license messaging to “free with all features included.”
docs/features/white-labeling.mdx Removes “Enterprise plan required” banner.
docs/features/mcp-server.mdx Updates MCP/IAM behavior docs for “IAM off when no rules.”
docs/features/database-access-control.mdx Updates IAM docs to describe opt-in enforcement when rules exist.
docs/features/audit-log.mdx Removes “Enterprise plan required” banner.
docs/docs.json Removes the license page from docs navigation.
docs/configuration/license.mdx Removes license management documentation page.
docs/configuration/config.mdx Removes license config field; updates branding/owner/IAM/agents wording.
docs/authentication/overview.mdx Updates SSO positioning text (no plan references).
docs/authentication/okta.mdx Removes plan requirement banner.
docs/authentication/keycloak.mdx Removes plan requirement banner.
docs/authentication/google.mdx Removes plan requirement banner.
.github/workflows/deploy-stripe-worker.yml Removes the Stripe worker deployment workflow.
Files not reviewed (1)
  • worker/stripe-webhook/package-lock.json: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/index.ts Outdated
import { connectRouter } from './connect'
import { mcpRouter, MCP_PATH } from './mcp'
import { loadConfig, loadConfigFromString, loadDemoConfig, isDemoMode, getBanner, getBranding, getExternalUrl, getPlan, getLicenseExpiry, getUsers, getLicenseMaxUsers, getLicenseEmail, getAgents } from './lib/config'
import { loadConfig, loadConfigFromString, loadDemoConfig, isDemoMode, getBanner, getBranding, getExternalUrl, getAgents } from './lib/config'
Comment thread server/index.ts
const userCount = getUsers().length
console.log(`✓ Plan: ${plan}, User seat: ${userCount}/${maxUsers}`)

// Test all connections to populate cache
IAM is now opt-in — with no [[iam]] rules, every authenticated principal
has full access. Emit a startup warning so an empty IAM section isn't a
silent misconfiguration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tianzhou tianzhou changed the title feat: remove pricing/licensing, make all features free feat: warn on startup when auth is enabled but no IAM rules exist Jun 25, 2026
@tianzhou tianzhou merged commit 4fea19c into main Jun 25, 2026
4 checks passed
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