Skip to content

fix(security): block bot user logins#9368

Merged
sriramveeraghanta merged 1 commit into
previewfrom
fix/block-bot-user-logins
Jul 7, 2026
Merged

fix(security): block bot user logins#9368
sriramveeraghanta merged 1 commit into
previewfrom
fix/block-bot-user-logins

Conversation

@sriramveeraghanta

@sriramveeraghanta sriramveeraghanta commented Jul 7, 2026

Copy link
Copy Markdown
Member

Description

Bot service accounts (User.is_bot=True, e.g. the WORKSPACE_SEED bot created in workspace_seed_task.py) are internal identities that are meant to act only through API tokens. Nothing previously stopped one from being driven through the interactive login flow if its email was known — letting a human assume a service identity.

This PR blocks bot users from every interactive login path while leaving their API-token access completely untouched (that is how bots are meant to operate).

  • Primary fix — one shared chokepoint. Every interactive provider (email/password, magic code, and all OAuth providers — Google, GitHub, GitLab, Gitea — across both the app and space surfaces) funnels through Adapter.complete_login_or_signup(). A single is_bot guard is added there, right beside the existing deactivated-account check. A brand-new signup can never be a bot (bots are provisioned internally), so guarding on an existing user record is sufficient.
  • Defense-in-depth — admin console. InstanceAdminSignInEndpoint mints its own admin session via user_login() outside the chokepoint. A bot is never registered as an InstanceAdmin and has a random autoset password, so this is not reachable today, but a guard is added there too to close the path. It reuses the existing ADMIN_AUTHENTICATION_FAILED code so no bot-specific error is disclosed.
  • New error code. BOT_USER_LOGIN_FORBIDDEN (5017) is added to the backend AUTHENTICATION_ERROR_CODES and plumbed end-to-end: the apps/web and apps/space auth helpers, plus the shared @plane/constants (EAuthErrorCodes) and @plane/utils (authErrorHandler message map + banner-alert list) packages, so any consumer of the shared handler renders it correctly rather than falling back to a generic error.

Bot API-token authentication (APIKeyAuthentication) does not pass through complete_login_or_signup() and is verified unaffected.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Test Scenarios

Added contract regression tests in apps/api/plane/tests/contract/app/test_authentication.py:

  • Bot blocked via password sign-in — an active bot with a correct password is rejected with BOT_USER_LOGIN_FORBIDDEN and no session is created.
  • Bot blocked via magic code — the same block applies through a second provider, proving the guard sits at the shared chokepoint.
  • Bot blocked at admin sign-in — an active bot is rejected at /api/instances/admins/sign-in/ with ADMIN_AUTHENTICATION_FAILED and no session is created.
  • Non-bot control — a normal user with the identical setup still signs in successfully (guard is scoped strictly to is_bot).

Manual scenarios to verify:

  1. Attempt to sign in (email/password, magic link, and any configured OAuth provider) using a bot account's email → login is refused with the "Sign in not allowed" banner; no session is established.
  2. Confirm a bot's API token continues to authenticate against the /api/ v1 surface (e.g. list projects) — programmatic access must still work.
  3. Confirm normal human users can still sign in and sign up through every provider.

References

  • Blocks interactive logins for is_bot service accounts; no linked issue.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Bot service accounts can no longer sign in through regular login or magic-code flows.
    • Admin console sign-in now blocks bot accounts as well.
    • Users who encounter this restriction will see a clear “Sign in not allowed” message directing them to use a personal account.

Bot service accounts (User.is_bot=True, e.g. the WORKSPACE_SEED bot) are
internal identities meant to act only through API tokens. Nothing stopped
one from being driven through the interactive login flow if its email was
known, letting a human assume a service identity.

Reject bot accounts at the shared login chokepoint,
Adapter.complete_login_or_signup(), right beside the existing
deactivated-account check. This covers every interactive provider in one
place: email/password, magic code, and all OAuth providers (Google, GitHub,
GitLab, Gitea) across both the app and space surfaces. Bot API-token access
is left untouched, since that is how bots are meant to operate.

Also add a defense-in-depth is_bot guard to InstanceAdminSignInEndpoint,
which mints its own admin session outside the chokepoint (a bot is never an
InstanceAdmin today, so this is not currently reachable, but it closes the
path regardless).

Surface the rejection with a new dedicated error code
BOT_USER_LOGIN_FORBIDDEN (5017), plumbed into the app and space frontend
error helpers as well as the shared @plane/constants and @plane/utils
packages (message map + banner-alert list) so any consumer of the shared
auth-error handler renders it correctly. The admin path reuses the existing
ADMIN_AUTHENTICATION_FAILED code so it discloses no bot-specific error.

Add contract regression tests: a bot blocked via password and via magic
code, a bot blocked at the admin sign-in endpoint, and a non-bot control
that still logs in.
Copilot AI review requested due to automatic review settings July 7, 2026 12:53
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

React Doctor found no issues. 🎉

⚠️ Warning: .github/workflows/react-doctor.yml is configured incorrectly. See below to fix.

React Doctor compares against preview to report only the issues this pull request introduces. This run couldn't complete that comparison (usually a shallow CI checkout with no merge base), so it listed every issue in the changed files, including ones that already existed on preview.

Add fetch-depth: 0 to the actions/checkout step in .github/workflows/react-doctor.yml so the checkout includes the history React Doctor needs:

 jobs:
   react-doctor:
     steps:
       - uses: actions/checkout@v5
+        with:
+          fetch-depth: 0

       - uses: millionco/react-doctor@v2

To silence this warning, set silence-missing-baseline-warning: true on the React Doctor action.

Reviewed by React Doctor for commit 7dbe221.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 48f42d13-ce91-48bb-916b-98c915526007

📥 Commits

Reviewing files that changed from the base of the PR and between 7fbf14a and 7dbe221.

📒 Files selected for processing (8)
  • apps/api/plane/authentication/adapter/base.py
  • apps/api/plane/authentication/adapter/error.py
  • apps/api/plane/license/api/views/admin.py
  • apps/api/plane/tests/contract/app/test_authentication.py
  • apps/space/helpers/authentication.helper.tsx
  • apps/web/helpers/authentication.helper.tsx
  • packages/constants/src/auth/index.ts
  • packages/utils/src/auth.ts

📝 Walkthrough

Walkthrough

Adds backend enforcement to reject bot service accounts from interactive login/signup and admin sign-in flows via a new BOT_USER_LOGIN_FORBIDDEN (5017) error code, contract tests validating the rejection, and matching frontend error code definitions, banner messages, and handler registrations in web, space, and shared packages.

Changes

Bot login block

Layer / File(s) Summary
Backend authentication guard and error code
apps/api/plane/authentication/adapter/base.py, apps/api/plane/authentication/adapter/error.py, apps/api/plane/license/api/views/admin.py
Adds BOT_USER_LOGIN_FORBIDDEN (5017) error code and enforces rejection of user.is_bot accounts in complete_login_or_signup() and the instance admin sign-in endpoint, redirecting with the appropriate error instead of proceeding with login.
Backend contract tests
apps/api/plane/tests/contract/app/test_authentication.py
Adds TestBotUserLoginBlocked and TestBotUserAdminSignInBlocked verifying bot password/magic-code/admin sign-in is blocked without session creation, while human sign-in remains allowed.
Frontend error code and banner messaging
apps/web/helpers/authentication.helper.tsx, apps/space/helpers/authentication.helper.tsx, packages/constants/src/auth/index.ts, packages/utils/src/auth.ts
Adds BOT_USER_LOGIN_FORBIDDEN = "5017" enum member, corresponding "Sign in not allowed" banner title/message, and registers the code in each authErrorHandler's banner alert list.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AuthAdapter
  participant AdminSignInEndpoint
  Client->>AuthAdapter: complete_login_or_signup()
  AuthAdapter->>AuthAdapter: check user.is_bot
  AuthAdapter-->>Client: raise AuthenticationException(BOT_USER_LOGIN_FORBIDDEN)
  Client->>AdminSignInEndpoint: post() sign-in request
  AdminSignInEndpoint->>AdminSignInEndpoint: check user.is_bot
  AdminSignInEndpoint-->>Client: redirect with ADMIN_AUTHENTICATION_FAILED
Loading

Suggested reviewers: pablohashescobar, dheeru0198, mguptahub

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: blocking bot user logins for security.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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 fix/block-bot-user-logins

Warning

Tools execution failed with the following error:

Failed to run tools: Stream initialization permanently failed: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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.

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 prevents bot/service accounts (User.is_bot=True) from authenticating through any interactive login mechanism, ensuring bots can only act via API tokens while normal user authentication remains unchanged.

Changes:

  • Added a backend guard in Adapter.complete_login_or_signup() to reject bot users with the new BOT_USER_LOGIN_FORBIDDEN (5017) error.
  • Added a defense-in-depth guard in the instance-admin sign-in endpoint to reject bots using the existing ADMIN_AUTHENTICATION_FAILED response.
  • Introduced and propagated the new error code (5017) through shared constants/utils and both apps/web and apps/space, plus added contract regression tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/utils/src/auth.ts Adds messaging + banner handling for BOT_USER_LOGIN_FORBIDDEN in the shared auth error handler.
packages/constants/src/auth/index.ts Adds EAuthErrorCodes.BOT_USER_LOGIN_FORBIDDEN = "5017".
apps/web/helpers/authentication.helper.tsx Adds the new error code + UI message mapping for the web app auth flow.
apps/space/helpers/authentication.helper.tsx Adds the new error code + UI message mapping for the space app auth flow.
apps/api/plane/tests/contract/app/test_authentication.py Adds contract regression tests ensuring bot users can’t sign in (password/magic) nor via admin sign-in.
apps/api/plane/license/api/views/admin.py Blocks bot users from instance-admin sign-in (defense-in-depth).
apps/api/plane/authentication/adapter/error.py Adds backend numeric error code mapping for BOT_USER_LOGIN_FORBIDDEN: 5017.
apps/api/plane/authentication/adapter/base.py Adds the shared chokepoint guard rejecting user.is_bot during interactive login/signup completion.

@sriramveeraghanta
sriramveeraghanta merged commit 4fc79a2 into preview Jul 7, 2026
19 of 21 checks passed
@sriramveeraghanta
sriramveeraghanta deleted the fix/block-bot-user-logins branch July 7, 2026 20:21
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.

3 participants