Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
6d413aa
feat(enterprise): SSO providers schema, API, OIDC auth flow (M1+M2)
alfredorubin96 May 7, 2026
6087c3c
feat(enterprise): Settings > Authentication admin page (M3)
alfredorubin96 May 7, 2026
4adc4ef
fix(a11y,e2e): add missing DialogDescription, fix E2E login flake
alfredorubin96 May 7, 2026
fd09dfd
feat(enterprise): Auth.js dynamic OIDC wiring + login page SSO button…
alfredorubin96 May 7, 2026
e354868
test(enterprise): E2E SSO flow with Keycloak Testcontainer (M5)
alfredorubin96 May 7, 2026
4579494
docs: add SSO configuration guide with IdP examples
alfredorubin96 May 7, 2026
fec8eda
feat(auth): env-based SSO config — single OIDC provider via env vars
alfredorubin96 May 7, 2026
268e1c3
feat(auth): support comma-separated values in SSO role mapping
alfredorubin96 May 8, 2026
62eeca8
docs: document comma-separated values in SSO role mapping
alfredorubin96 May 8, 2026
5b030cc
feat(auth): gate env-based SSO behind NEOBOARD_EDITION=enterprise
alfredorubin96 May 8, 2026
2f86db9
docs: fix SSO docs to consistently require NEOBOARD_EDITION=enterprise
alfredorubin96 May 8, 2026
d41f8be
docs: restructure documentation into topic-based sections (#705, #708)
alfredorubin96 May 8, 2026
62c52f6
fix(ci): update package-lock.json with enterprise workspace
alfredorubin96 May 8, 2026
9bc898a
fix(e2e): use exact match for 'Sign in' button in all E2E tests
alfredorubin96 May 8, 2026
56d6548
fix(e2e): update CORS test to match #689 security hardening
alfredorubin96 May 8, 2026
ecbe520
fix(auth,security): address CodeRabbit findings on PR #702
alfredorubin96 May 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/sync-public-exclude
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Paths excluded from the public mirror by sync-public.yml.
# Each line maps to a --path argument passed to git filter-repo --invert-paths.
#
# To add a new exclusion:
# 1. Add the path here
# 2. Add a matching --path line in .github/workflows/sync-public.yml
enterprise/
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
- 'component/**'
- 'connection/**'
- 'cli/**'
- 'enterprise/**'
- 'sonar-project.properties'
- 'Dockerfile'
- '.github/workflows/ci.yml'
Expand All @@ -20,6 +21,7 @@ on:
- 'component/**'
- 'connection/**'
- 'cli/**'
- 'enterprise/**'
- 'sonar-project.properties'
- 'Dockerfile'
- '.github/workflows/ci.yml'
Expand Down Expand Up @@ -126,12 +128,17 @@ jobs:
CONN_PID=$!
cd cli && npm run test:coverage &
CLI_PID=$!
if [ -d enterprise ]; then
cd enterprise && npm run test &
ENT_PID=$!
fi

FAIL=0
wait $APP_PID || FAIL=1
wait $COMP_PID || FAIL=1
wait $CONN_PID || FAIL=1
wait $CLI_PID || FAIL=1
[ -n "${ENT_PID:-}" ] && { wait $ENT_PID || FAIL=1; }
exit $FAIL
env:
POSTGRES_HOST: localhost
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/sync-public.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Sync to Public Mirror

# This workflow runs in the PRIVATE repo (neoboard-private) and pushes
# a filtered copy (without enterprise/) to the public repo (neoboard).
#
# Required secret: PUBLIC_REPO_TOKEN — a GitHub PAT with repo push access
# to alfredo1996/neoboard.

on:
push:
branches: [main, dev]
workflow_dispatch:

jobs:
sync:
runs-on: ubuntu-latest
steps:
Comment on lines +14 to +17

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Set explicit least-privilege workflow permissions.

This job doesn’t define permissions, so it inherits repo/org defaults. For a mirror sync job, explicitly pin permissions to reduce accidental token overreach.

Suggested patch
 on:
   push:
     branches: [main, dev]
   workflow_dispatch:

+permissions:
+  contents: read
+
 jobs:
   sync:
     runs-on: ubuntu-latest

As per coding guidelines "CI workflows: check for secret exposure, unnecessary permissions, and that coverage is generated before any SonarQube scan step."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/sync-public.yml around lines 14 - 17, Add an explicit
least-privilege permissions block to the GitHub Actions job by updating
jobs.sync to include a permissions stanza that only grants the token scopes
required for the mirror sync (e.g., contents: read or contents: write as
applicable, and no other scopes), removing reliance on repo/org defaults; also
ensure no unnecessary permissions are granted and verify that any steps that
require coverage generation run before any SonarQube scan step and that secrets
are not exposed in the job.

- name: Checkout private repo (full history)
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install git-filter-repo
run: pip install git-filter-repo

- name: Remove enterprise/ from history
run: |
git filter-repo \
--force \
--invert-paths \
--path enterprise/

- name: Push to public mirror
run: |
git remote add public \
https://x-access-token:${{ secrets.PUBLIC_REPO_TOKEN }}@github.com/alfredo1996/neoboard.git
git push public HEAD:refs/heads/${{ github.ref_name }} --force
19 changes: 19 additions & 0 deletions app/drizzle/migrations/0004_busy_champions.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CREATE TYPE "public"."sso_protocol" AS ENUM('oidc');--> statement-breakpoint
CREATE TABLE "sso_provider" (
"id" text PRIMARY KEY NOT NULL,
"tenant_id" text DEFAULT 'default' NOT NULL,
"name" text NOT NULL,
"protocol" "sso_protocol" DEFAULT 'oidc' NOT NULL,
"issuer" text NOT NULL,
"client_id" text NOT NULL,
"client_secret_encrypted" text NOT NULL,
"scopes" text DEFAULT 'openid profile email' NOT NULL,
"claim_mappings" jsonb,
"auto_provision" boolean DEFAULT true NOT NULL,
"default_role" "user_role" DEFAULT 'creator' NOT NULL,
"enforce_sso" boolean DEFAULT false NOT NULL,
"enabled" boolean DEFAULT true NOT NULL,
"created_at" timestamp DEFAULT now(),
"updated_at" timestamp DEFAULT now(),
CONSTRAINT "sso_provider_tenant_issuer_unique" UNIQUE("tenant_id","issuer")
);
Loading
Loading