Skip to content

Add Entra OIDC auth, chat/search UX overhaul, and supporting fixes#45

Merged
rajivml merged 10 commits into
feature/darwinfrom
rajiv/add-claude
May 28, 2026
Merged

Add Entra OIDC auth, chat/search UX overhaul, and supporting fixes#45
rajivml merged 10 commits into
feature/darwinfrom
rajiv/add-claude

Conversation

@rajivml
Copy link
Copy Markdown
Collaborator

@rajivml rajivml commented May 28, 2026

Brings the rajiv/add-claude branch up to feature/darwin: Microsoft/Entra OIDC auth wired into the OSS code path (no ee/ dependency), a chat & search UX overhaul, a chat-page crash fix, a persona-deletion permission gap close, per-channel Slack-bot model config, and Playwright MCP tooling. 9 commits, 50 files, +909 / −582.

Auth — Microsoft/Entra OIDC

Wired directly into the OSS app (no ee/ dependency):

  • OIDC router registered in backend/danswer/main.py; AuthType.OIDC allowlisted in verify_auth_setting; public auth routes registered.
  • New env vars: OPENID_CONFIG_URL, DEFAULT_ADMIN_EMAILS.
  • Auto-verify OIDC users in oauth_callback; env-driven admin allowlist promotes addresses in DEFAULT_ADMIN_EMAILS.
  • backend/requirements/default.txt: pin bcrypt==4.0.1 (passlib 1.7.4 is incompatible with bcrypt 4.1+; do not bump without also fixing passlib).

Kubernetes (darwin-kubernetes/)

  • env-configmap.yaml: AUTH_TYPE=oidc, OPENID_CONFIG_URL (Entra discovery), DEFAULT_ADMIN_EMAILS; WEB_DOMAIN/DOMAIN set to the external https:// origin (required for a correct OIDC redirect_uri and a Secure session cookie).
  • api_server-service-deployment.yaml: inject OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, USER_AUTH_SECRET from the danswer-secrets secret via secretKeyRef.
  • secrets.yaml: stub values replaced with documented placeholders + a "do not commit real secrets" header — real values are applied out-of-band.

Chat & search UX

  • Persona scoping is now an outer fence: persona document_sets intersect with user-applied filters server-side in search/preprocessing/preprocessing.py (the input-bar "Scope" chips are gone but the scoping itself is unchanged).
  • Search-mode framing on the default persona; assistant scope chip; starter prompts; sidebar timestamps on chat history; Cmd+K to start a new chat; distinct assistant message styling; 3-step onboarding cards on the empty chat page; larger chat input.
  • Searchable / scrollable knowledge-set pickerFiltersTab.tsx and ChatFilters.tsx were significantly rewritten (−188 / −176 lines) around the new picker. Tag filters were removed.
  • /search hidden from nav (still reachable by URL); removed the redundant top-left assistant selector; highlight applied filters.
  • web/next.config.js: dropped the 308 stream redirects that were stripping the session cookie.
  • Switching assistants now shows an auto-expiring toast explaining that each chat is bound to a single assistant (and that any attached files need to be re-uploaded). Previously this silently created and navigated to a new chat session.
  • Fresh installs default to the chat page (Settings.default_page = CHAT). Existing deployments keep their persisted value — change via Admin → Settings.

Bug fixes

  • Chat doc-render crash (web/src/components/search/DocumentDisplay.tsx): fall back to blurb when match_highlights is a non-empty array of only falsy/whitespace strings. Previously sections[0][2] threw Cannot read properties of undefined (reading '2'), crashing the chat doc sidebar and the search page when retrieved docs had empty highlights — more likely with large or many-doc contexts.
  • Slack code fences: strip the language token off opening fences in build_qa_response_blocks. Slack mrkdwn has no info string, so the language was rendering as a literal first line of the block. (Slack still cannot syntax-highlight; that's a platform limit.)
  • Persona "Scope" chips removed from the chat input bar (SelectedFilterDisplay, ChatInputBar) — cosmetic only; server-side scoping unchanged.

Security / permissions

  • mark_persona_as_deleted (backend/danswer/db/persona.py) now returns 403 for non-admins on default_persona or ownerless (user_id IS NULL) personas, mirroring the frontend's !default_persona rule. Closes a gap where a basic user could soft-delete a shared default assistant for everyone via a direct API call (get_persona_by_id grants non-admins access to ownerless personas).

Slack bot

  • Configure LLM models per channel (SlackBotConfigCreationForm.tsx, server/manage/slack_bot.py, server/manage/models.py).

Tooling

  • Track .mcp.json (shared Playwright MCP server) so the browser-driven debugging setup is reproducible across the team.
  • .gitignore — ignore .playwright-mcp/ session output and the ad-hoc model-picker-open.png screenshot (they are local artifacts, not source).
  • Removed a stale Playwright MCP log file.

Configuration required for reviewers / operators

Before this can be deployed, the following must be set:

Setting Where Notes
`OPENID_CONFIG_URL` env-configmap Entra `.well-known/openid-configuration` URL for the tenant
`DEFAULT_ADMIN_EMAILS` env-configmap Comma-separated allowlist
`WEB_DOMAIN` / `DOMAIN` env-configmap External `https://` origin
`OAUTH_CLIENT_ID` / `OAUTH_CLIENT_SECRET` / `USER_AUTH_SECRET` `danswer-secrets` Applied out-of-band; placeholders in `secrets.yaml`

Footguns

  • Don't bump bcrypt past 4.0.1 without also fixing passlib (1.7.4 is incompatible with 4.1+).
  • Don't re-introduce the 308 stream redirects in `next.config.js` — they stripped the session cookie.
  • Setting `WEB_DOMAIN` incorrectly will break the OIDC `redirect_uri`.

Commits

SHA Subject
`3597c574` Add option to configure models for channel
`21dd20a9` Remove stale Playwright MCP log file
`d8ac3fb5` Add Entra OIDC auth and chat/search UX improvements
`f04b2c74` Fix chat doc-render crash, Slack code fences, drop persona scope chips
`a6461d51` k8s: wire Entra OIDC auth config (placeholders only, no real secrets)
`df883fe2` chat: toast when switching assistants starts a new session
`7e053e85` settings: default fresh installs to the chat page
`92500872` persona: block non-admins from deleting default/shared assistants
`864c513c` tooling: add Playwright MCP config, ignore its session artifacts

🤖 Generated with Claude Code

Sarath1018 and others added 10 commits May 25, 2026 15:40
Auth:
- Wire Microsoft/Entra OIDC directly into the OSS app (no ee/ dependency):
  OIDC router in main.py, AuthType.OIDC allowlisted, public auth routes
  registered, OPENID_CONFIG_URL + DEFAULT_ADMIN_EMAILS env vars.
- Auto-verify OIDC users in oauth_callback; env-driven admin allowlist.
- Pin bcrypt==4.0.1 (passlib 1.7.4 incompatible with bcrypt 4.1+).

Chat/search UX:
- Persona document_sets act as an outer fence (intersect with user filters).
- Search-mode framing on the default persona; assistant scope chip; starter
  prompts; sidebar timestamps; Cmd+K new chat; distinct assistant message
  styling; 3-step onboarding cards; larger chat input.
- Searchable/scrollable knowledge-set picker; removed tag filters.
- Hide /search from nav (still reachable by URL); remove redundant top-left
  assistant selector; highlight applied filters.
- next.config.js: drop 308 stream redirects that stripped the session cookie.

Docs: AGENTS.md + CONTRIBUTING.md updated for OIDC setup and the new footguns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- DocumentDisplay: fall back to blurb when match_highlights is a non-empty
  array of only falsy/whitespace strings. Previously sections stayed empty and
  sections[0][2] threw "Cannot read properties of undefined (reading '2')",
  crashing the chat doc sidebar (and search page) when retrieved docs had empty
  highlights — more likely with large/many-doc contexts.

- Slack blocks: strip the language token off opening code fences (```bash ->
  ```) in build_qa_response_blocks. Slack mrkdwn has no fenced-code info string,
  so the language rendered as a literal first line of the block. (Slack still
  cannot syntax-highlight; that's a platform limit.)

- SelectedFilterDisplay/ChatInputBar: remove the locked persona "Scope" chips
  from the chat input bar. Cosmetic only — the assistant still scopes search to
  its document sets server-side in search/preprocessing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- env-configmap: AUTH_TYPE=oidc, OPENID_CONFIG_URL (Entra discovery),
  DEFAULT_ADMIN_EMAILS, and set WEB_DOMAIN/DOMAIN to the external https origin
  (required for a correct OIDC redirect_uri and Secure session cookie).
- api_server deployment: inject OAUTH_CLIENT_ID/OAUTH_CLIENT_SECRET/
  USER_AUTH_SECRET from the danswer-secrets secret via secretKeyRef.
- secrets.yaml: replace stub values with documented placeholders and a
  "do not commit real secrets" header; real values applied out-of-band.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switching the assistant silently created and navigated to a new chat session with no feedback. Show an auto-expiring toast explaining each chat is bound to a single assistant (and to re-upload any attached files).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Settings.default_page now defaults to CHAT instead of SEARCH. Only affects deployments with no stored settings yet; existing deployments keep their persisted value (change via Admin -> Settings).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
get_persona_by_id grants non-admins access to ownerless personas (user_id IS NULL), which includes the shared default assistants. Guard mark_persona_as_deleted so a basic user gets 403 for default/ownerless personas, mirroring the frontend's !default_persona rule. Closes a gap where a basic user could soft-delete a default assistant for everyone via a direct API call.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Track .mcp.json (shared Playwright MCP server) so the browser-driven
debugging setup is reproducible. Gitignore .playwright-mcp/ and the
ad-hoc screenshot, which are local session output, not source.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Out of scope for the OIDC / UX work; revisit separately.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rajivml rajivml merged commit 9f0c210 into feature/darwin May 28, 2026
5 of 6 checks passed
rajivml added a commit that referenced this pull request May 29, 2026
rajiv/add-claude was merged to feature/darwin upstream, so the doc's
"on top of rajiv/add-claude (PR #45)" reference is stale. The branch
is now rebased onto origin/feature/darwin directly — same diff, just
a fresher base.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rajivml added a commit that referenced this pull request May 29, 2026
rajiv/add-claude was merged to feature/darwin upstream, so the doc's
"on top of rajiv/add-claude (PR #45)" reference is stale. The branch
is now rebased onto origin/feature/darwin directly — same diff, just
a fresher base.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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