Skip to content

Commit 0b5b181

Browse files
authored
Feat/860 enterprise multitenancy, role-based access control, JWT revocation and SSO (#862)
* Multitenancy support Signed-off-by: Mihai Criveti <[email protected]> * Cleanup comments and duplicate env Signed-off-by: Mihai Criveti <[email protected]> * Cleanup comments and duplicate env Signed-off-by: Mihai Criveti <[email protected]> * Fix smoketest Signed-off-by: Mihai Criveti <[email protected]> * Fix docker-compose Signed-off-by: Mihai Criveti <[email protected]> * Fix postgres Signed-off-by: Mihai Criveti <[email protected]> * .env.example update Signed-off-by: Mihai Criveti <[email protected]> * flake8 alembic script Signed-off-by: Mihai Criveti <[email protected]> * Update helm charts Signed-off-by: Mihai Criveti <[email protected]> * Update docs Signed-off-by: Mihai Criveti <[email protected]> * Update docstring Signed-off-by: Mihai Criveti <[email protected]> * Update docstring Signed-off-by: Mihai Criveti <[email protected]> * Update docstring Signed-off-by: Mihai Criveti <[email protected]> * Update ruff Signed-off-by: Mihai Criveti <[email protected]> * Update docs Signed-off-by: Mihai Criveti <[email protected]> * Update doctest Signed-off-by: Mihai Criveti <[email protected]> * Update doctest 45% Signed-off-by: Mihai Criveti <[email protected]> * Fix blocking removal of last admin Signed-off-by: Mihai Criveti <[email protected]> * Fix blocking removal of last admin Signed-off-by: Mihai Criveti <[email protected]> * Fix number of team members Signed-off-by: Mihai Criveti <[email protected]> * Fix team approval workflow Signed-off-by: Mihai Criveti <[email protected]> * Fix logs Signed-off-by: Mihai Criveti <[email protected]> * Fix logs Signed-off-by: Mihai Criveti <[email protected]> * Add multitenancy scripts to check migration Signed-off-by: Mihai Criveti <[email protected]> * Add multitenancy scripts to check migration Signed-off-by: Mihai Criveti <[email protected]> * Add manual testing Signed-off-by: Mihai Criveti <[email protected]> * Add manual testing Signed-off-by: Mihai Criveti <[email protected]> * Add manual testing Signed-off-by: Mihai Criveti <[email protected]> * Fix gateways a2a and prompts migration Signed-off-by: Mihai Criveti <[email protected]> * Fix APP_ROOT_PATH Signed-off-by: Mihai Criveti <[email protected]> * Fix APP_ROOT_PATH part 2 Signed-off-by: Mihai Criveti <[email protected]> * flake8 Signed-off-by: Mihai Criveti <[email protected]> * Update names in UI Signed-off-by: Mihai Criveti <[email protected]> * Update Tools samples for Bulk Import Signed-off-by: Mihai Criveti <[email protected]> * Update docs for password change Signed-off-by: Mihai Criveti <[email protected]> * Add 2nd pass. check field Signed-off-by: Mihai Criveti <[email protected]> * Add 2nd pass. check field Signed-off-by: Mihai Criveti <[email protected]> * Fix missing token_usage_logs migration Signed-off-by: Mihai Criveti <[email protected]> * Fix missing token_usage_logs migration Signed-off-by: Mihai Criveti <[email protected]> * Fix JSON types during migration Signed-off-by: Mihai Criveti <[email protected]> * Fix JSON types during migration Signed-off-by: Mihai Criveti <[email protected]> * Major refactor migration Signed-off-by: Mihai Criveti <[email protected]> * Major refactor migration Signed-off-by: Mihai Criveti <[email protected]> * Fix flake8 Signed-off-by: Mihai Criveti <[email protected]> * Fix import Signed-off-by: Mihai Criveti <[email protected]> * Fix import Signed-off-by: Mihai Criveti <[email protected]> * Fix import Signed-off-by: Mihai Criveti <[email protected]> * Fix import Signed-off-by: Mihai Criveti <[email protected]> * Fix tests Signed-off-by: Mihai Criveti <[email protected]> --------- Signed-off-by: Mihai Criveti <[email protected]>
1 parent c30cbf5 commit 0b5b181

File tree

255 files changed

+44070
-3990
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

255 files changed

+44070
-3990
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ test/
2020
attic/
2121
*.md
2222
.benchmarks/
23+
.claude
2324

2425
# Development environment directories
2526
.devcontainer/

.env.example

Lines changed: 139 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,27 @@
33
#####################################
44

55
# Basic Server Configuration
6+
APP_NAME=MCP_Gateway
67
HOST=0.0.0.0
78
PORT=4444
89
ENVIRONMENT=development
910
APP_DOMAIN=localhost
11+
APP_ROOT_PATH=""
12+
13+
# Enable basic auth for docs endpoints
14+
DOCS_ALLOW_BASIC_AUTH=false
1015

1116
# Database Configuration
1217
DATABASE_URL=sqlite:///./mcp.db
1318
# DATABASE_URL=postgresql://postgres:mysecretpassword@localhost:5432/mcp
1419
# DATABASE_URL=mysql+pymysql://mysql:changeme@localhost:3306/mcp
1520

21+
# Database Connection Pool Configuration (for performance optimization)
22+
# DB_POOL_SIZE=50 # Maximum number of persistent connections (default: 200, SQLite capped at 50)
23+
# DB_MAX_OVERFLOW=20 # Additional connections beyond pool_size (default: 10, SQLite capped at 20)
24+
# DB_POOL_TIMEOUT=30 # Seconds to wait for connection before timeout (default: 30)
25+
# DB_POOL_RECYCLE=3600 # Seconds before recreating connection (default: 3600)
26+
1627
# Cache Configuration
1728
CACHE_TYPE=database
1829
# CACHE_TYPE=redis
@@ -39,8 +50,6 @@ PROTOCOL_VERSION=2025-03-26
3950
# Admin UI basic-auth credentials
4051
# PRODUCTION: Change these to strong, unique values!
4152
# Authentication Configuration
42-
JWT_SECRET_KEY=my-test-key
43-
JWT_ALGORITHM=HS256
4453
BASIC_AUTH_USER=admin
4554
BASIC_AUTH_PASSWORD=changeme
4655
AUTH_REQUIRED=true
@@ -52,10 +61,49 @@ JWT_SECRET_KEY=my-test-key
5261
# Algorithm used to sign JWTs (e.g., HS256)
5362
JWT_ALGORITHM=HS256
5463

64+
# JWT Audience and Issuer claims for token validation
65+
# PRODUCTION: Set these to your service-specific values
66+
JWT_AUDIENCE=mcpgateway-api
67+
JWT_ISSUER=mcpgateway
68+
5569
# Expiry time for generated JWT tokens (in minutes; e.g. 7 days)
5670
TOKEN_EXPIRY=10080
5771
REQUIRE_TOKEN_EXPIRATION=false
5872

73+
#####################################
74+
# Email-Based Authentication
75+
#####################################
76+
77+
# Enable email-based authentication system
78+
EMAIL_AUTH_ENABLED=true
79+
80+
# Platform admin user (bootstrap from environment)
81+
# PRODUCTION: Change these to your actual admin credentials!
82+
PLATFORM_ADMIN_EMAIL=[email protected]
83+
PLATFORM_ADMIN_PASSWORD=changeme
84+
PLATFORM_ADMIN_FULL_NAME=Platform Administrator
85+
86+
# Argon2id Password Hashing Configuration
87+
# Time cost (iterations) - higher = more secure but slower
88+
ARGON2ID_TIME_COST=3
89+
# Memory cost (KB) - higher = more secure but uses more RAM
90+
ARGON2ID_MEMORY_COST=65536
91+
# Parallelism (threads) - typically 1 for web apps
92+
ARGON2ID_PARALLELISM=1
93+
94+
# Password Policy Configuration
95+
PASSWORD_MIN_LENGTH=8
96+
PASSWORD_REQUIRE_UPPERCASE=false
97+
PASSWORD_REQUIRE_LOWERCASE=false
98+
PASSWORD_REQUIRE_NUMBERS=false
99+
PASSWORD_REQUIRE_SPECIAL=false
100+
101+
# Account Security Configuration
102+
# Maximum failed login attempts before account lockout
103+
MAX_FAILED_LOGIN_ATTEMPTS=5
104+
# Account lockout duration in minutes
105+
ACCOUNT_LOCKOUT_DURATION_MINUTES=30
106+
59107
# MCP Client Authentication
60108
MCP_CLIENT_AUTH_ENABLED=true
61109
TRUST_PROXY_AUTH=false
@@ -65,16 +113,80 @@ PROXY_USER_HEADER=X-Authenticated-User
65113
# Must be a non-empty string (e.g. passphrase or random secret)
66114
AUTH_ENCRYPTION_SECRET=my-test-salt
67115

116+
# OAuth Configuration
117+
OAUTH_REQUEST_TIMEOUT=30
118+
OAUTH_MAX_RETRIES=3
119+
120+
# ==============================================================================
121+
# SSO (Single Sign-On) Configuration
122+
# ==============================================================================
123+
124+
# Master SSO switch - enable Single Sign-On authentication
125+
SSO_ENABLED=false
126+
127+
# GitHub OAuth Configuration
128+
SSO_GITHUB_ENABLED=false
129+
# SSO_GITHUB_CLIENT_ID=your-github-client-id
130+
# SSO_GITHUB_CLIENT_SECRET=your-github-client-secret
131+
132+
# Google OAuth Configuration
133+
SSO_GOOGLE_ENABLED=false
134+
# SSO_GOOGLE_CLIENT_ID=your-google-client-id.googleusercontent.com
135+
# SSO_GOOGLE_CLIENT_SECRET=your-google-client-secret
136+
137+
# IBM Security Verify OIDC Configuration
138+
SSO_IBM_VERIFY_ENABLED=false
139+
# SSO_IBM_VERIFY_CLIENT_ID=your-ibm-verify-client-id
140+
# SSO_IBM_VERIFY_CLIENT_SECRET=your-ibm-verify-client-secret
141+
# SSO_IBM_VERIFY_ISSUER=https://your-tenant.verify.ibm.com/oidc/endpoint/default
142+
143+
# Okta OIDC Configuration
144+
SSO_OKTA_ENABLED=false
145+
# SSO_OKTA_CLIENT_ID=your-okta-client-id
146+
# SSO_OKTA_CLIENT_SECRET=your-okta-client-secret
147+
# SSO_OKTA_ISSUER=https://your-okta-domain.okta.com
148+
149+
# SSO General Settings
150+
SSO_AUTO_CREATE_USERS=true
151+
# JSON array of trusted email domains, e.g., ["example.com", "company.org"]
152+
SSO_TRUSTED_DOMAINS=[]
153+
# Keep local admin authentication when SSO is enabled
154+
SSO_PRESERVE_ADMIN_AUTH=true
155+
156+
# SSO Admin Assignment Settings
157+
# Email domains that automatically get admin privileges, e.g., ["yourcompany.com"]
158+
SSO_AUTO_ADMIN_DOMAINS=[]
159+
# GitHub organizations whose members get admin privileges, e.g., ["your-org", "partner-org"]
160+
SSO_GITHUB_ADMIN_ORGS=[]
161+
# Google Workspace domains that get admin privileges, e.g., ["company.com"]
162+
SSO_GOOGLE_ADMIN_DOMAINS=[]
163+
# Require admin approval for new SSO registrations
164+
SSO_REQUIRE_ADMIN_APPROVAL=false
165+
166+
#####################################
167+
# Personal Teams Configuration
168+
#####################################
169+
170+
# Enable automatic personal team creation for new users
171+
AUTO_CREATE_PERSONAL_TEAMS=true
172+
173+
# Personal team naming prefix
174+
PERSONAL_TEAM_PREFIX=personal
175+
176+
# Team Limits
177+
MAX_TEAMS_PER_USER=50
178+
MAX_MEMBERS_PER_TEAM=100
179+
180+
# Team Invitation Settings
181+
INVITATION_EXPIRY_DAYS=7
182+
REQUIRE_EMAIL_VERIFICATION_FOR_INVITES=true
183+
68184
#####################################
69185
# Admin UI and API Toggles
70186
#####################################
71187

72188
# Enable the visual Admin UI (true/false)
73189
# PRODUCTION: Set to false for security
74-
MCPGATEWAY_UI_ENABLED=true
75-
76-
# Enable the Admin API endpoints (true/false)
77-
# PRODUCTION: Set to false for security
78190

79191
# UI/Admin Feature Flags
80192
MCPGATEWAY_UI_ENABLED=true
@@ -143,12 +255,12 @@ CORS_ALLOW_CREDENTIALS=true
143255
# Environment setting (development/production) - affects security defaults
144256
# development: Auto-configures CORS for localhost:3000, localhost:8080, etc.
145257
# production: Uses APP_DOMAIN for HTTPS origins, enforces secure cookies
146-
ENVIRONMENT=development
258+
# ENVIRONMENT is already defined in Basic Server Configuration section
147259

148260
# Domain configuration for production CORS origins
149261
# In production, automatically creates origins: https://APP_DOMAIN, https://app.APP_DOMAIN, https://admin.APP_DOMAIN
150262
# For production: set to your actual domain (e.g., mycompany.com)
151-
APP_DOMAIN=localhost
263+
# APP_DOMAIN is already defined in Basic Server Configuration section
152264

153265
# Security settings for cookies
154266
# production: Automatically enables secure cookies regardless of this setting
@@ -190,7 +302,7 @@ REMOVE_SERVER_HEADERS=true
190302

191303
# Enable HTTP Basic Auth for docs endpoints (in addition to Bearer token auth)
192304
# Uses the same credentials as BASIC_AUTH_USER and BASIC_AUTH_PASSWORD
193-
DOCS_ALLOW_BASIC_AUTH=false
305+
# DOCS_ALLOW_BASIC_AUTH is already defined in Basic Server Configuration section
194306

195307
#####################################
196308
# Retry Config for HTTP Requests
@@ -209,32 +321,18 @@ RETRY_JITTER_MAX=0.5
209321
#####################################
210322

211323
# Logging verbosity level: DEBUG, INFO, WARNING, ERROR, CRITICAL
212-
MCPGATEWAY_BULK_IMPORT_MAX_TOOLS=200
213-
MCPGATEWAY_BULK_IMPORT_RATE_LIMIT=10
214-
215-
# Security Configuration
216-
SECURITY_HEADERS_ENABLED=true
217-
CORS_ALLOW_CREDENTIALS=true
218-
SECURE_COOKIES=true
219-
COOKIE_SAMESITE=lax
220-
X_FRAME_OPTIONS=DENY
221-
HSTS_ENABLED=true
222-
HSTS_MAX_AGE=31536000
223-
HSTS_INCLUDE_SUBDOMAINS=true
224-
REMOVE_SERVER_HEADERS=true
225-
226-
# CORS Configuration
227-
ALLOWED_ORIGINS=["http://localhost", "http://localhost:4444"]
228324

229325
# Logging Configuration
230326
LOG_LEVEL=INFO
231327
LOG_FORMAT=json
232328
LOG_TO_FILE=false
329+
LOG_FILEMODE=a+
330+
LOG_FILE=mcpgateway.log
331+
LOG_FOLDER=logs
233332
LOG_ROTATION_ENABLED=false
234333
LOG_MAX_SIZE_MB=1
235334
LOG_BACKUP_COUNT=5
236-
LOG_FILE=mcpgateway.log
237-
LOG_FOLDER=logs
335+
LOG_BUFFER_SIZE_MB=1.0
238336

239337
# Transport Configuration
240338
TRANSPORT_TYPE=all
@@ -243,6 +341,10 @@ SSE_RETRY_TIMEOUT=5000
243341
SSE_KEEPALIVE_ENABLED=true
244342
SSE_KEEPALIVE_INTERVAL=30
245343

344+
# Streaming HTTP Configuration
345+
USE_STATEFUL_SESSIONS=false
346+
JSON_RESPONSE_ENABLED=true
347+
246348
# Federation Configuration
247349
FEDERATION_ENABLED=true
248350
FEDERATION_DISCOVERY=false
@@ -260,6 +362,7 @@ TOOL_TIMEOUT=60
260362
MAX_TOOL_RETRIES=3
261363
TOOL_RATE_LIMIT=100
262364
TOOL_CONCURRENT_LIMIT=10
365+
GATEWAY_TOOL_NAME_SEPARATOR=-
263366

264367
# Prompt Configuration
265368
PROMPT_CACHE_SIZE=100
@@ -270,14 +373,22 @@ PROMPT_RENDER_TIMEOUT=10
270373
HEALTH_CHECK_INTERVAL=60
271374
HEALTH_CHECK_TIMEOUT=10
272375
UNHEALTHY_THRESHOLD=5
376+
GATEWAY_VALIDATION_TIMEOUT=5
273377

274378
# OpenTelemetry Configuration
275379
OTEL_ENABLE_OBSERVABILITY=true
276380
OTEL_TRACES_EXPORTER=otlp
277381
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
278382
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
279383
OTEL_EXPORTER_OTLP_INSECURE=true
384+
# OTEL_EXPORTER_OTLP_HEADERS=key1=value1,key2=value2
385+
# OTEL_EXPORTER_JAEGER_ENDPOINT=http://localhost:14268/api/traces
386+
# OTEL_EXPORTER_ZIPKIN_ENDPOINT=http://localhost:9411/api/v2/spans
280387
OTEL_SERVICE_NAME=mcp-gateway
388+
# OTEL_RESOURCE_ATTRIBUTES=service.version=1.0.0,environment=production
389+
OTEL_BSP_MAX_QUEUE_SIZE=2048
390+
OTEL_BSP_MAX_EXPORT_BATCH_SIZE=512
391+
OTEL_BSP_SCHEDULE_DELAY=5000
281392

282393
# Plugin Configuration
283394
PLUGINS_ENABLED=false
@@ -331,7 +442,7 @@ WELL_KNOWN_CACHE_MAX_AGE=3600
331442
DEV_MODE=false
332443
RELOAD=false
333444
DEBUG=false
334-
SKIP_SSL_VERIFY=false
445+
# SKIP_SSL_VERIFY is already defined in Security and CORS section
335446

336447
# Header Passthrough (WARNING: Security implications)
337448
ENABLE_HEADER_PASSTHROUGH=false

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
vulture mcpgateway --min-confidence 80
7171
7272
- id: pylint
73-
setup: pip install pylint
73+
setup: pip install pylint pylint-pydantic
7474
cmd: pylint mcpgateway --errors-only --fail-under=10
7575

7676
- id: interrogate

.github/workflows/pytest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
--cov-fail-under=70
8585
8686
# -----------------------------------------------------------
87-
# 4️⃣ Run doctests (fail under 545 coverage)
87+
# 4️⃣ Run doctests (fail under 40% coverage)
8888
# -----------------------------------------------------------
8989
- name: 📊 Doctest coverage with threshold
9090
run: |
@@ -93,7 +93,7 @@ jobs:
9393
--cov=mcpgateway \
9494
--cov-report=term \
9595
--cov-report=json:doctest-coverage.json \
96-
--cov-fail-under=45 \
96+
--cov-fail-under=40 \
9797
--tb=short
9898
9999
# -----------------------------------------------------------

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
*cookies*txt
2+
cookies*
3+
cookies.txt
14
.claude
25
mcpgateway-export*
36
mutants

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ repos:
368368
description: Verifies test files in tests/ directories start with `test_`.
369369
language: python
370370
files: (^|/)tests/.+\.py$
371-
exclude: ^tests/(.*/)?(pages|helpers|fuzzers|scripts|fixtures|migration)/.*\.py$|^tests/migration/.*\.py$ # Exclude page object, helper, fuzzer, script, fixture, and migration files
371+
exclude: ^tests/(.*/)?(pages|helpers|fuzzers|scripts|fixtures|migration|utils|manual)/.*\.py$|^tests/migration/.*\.py$ # Exclude page object, helper, fuzzer, script, fixture, util, manual, and migration files
372372
args: [--pytest-test-first] # `test_.*\.py`
373373

374374
# - repo: https://github.com/pycqa/flake8

.pylintrc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,10 @@ disable=raw-checker-failed,
446446
too-many-lines,
447447
too-many-branches,
448448
too-many-statements,
449-
too-many-public-methods
449+
too-many-public-methods,
450+
unsubscriptable-object
450451

451-
# TODO: remove most of the disabled onews above
452+
# TODO: remove most of the disabled items above
452453

453454
# Enable the message, report, category or checker with the given id(s). You can
454455
# either give multiple identifier separated by comma (,) or put this option

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
- `make clean`: Remove caches, build artefacts, venv, coverage, docs, certs.
3030

3131
MCP helpers
32-
- JWT token: `python -m mcpgateway.utils.create_jwt_token --username admin --exp 10080 --secret KEY`.
32+
- JWT token: `python -m mcpgateway.utils.create_jwt_token --username admin@example.com --exp 10080 --secret KEY`.
3333
- Expose stdio server: `python -m mcpgateway.translate --stdio "uvx mcp-server-git" --port 9000`.
3434

3535
## Coding Style & Naming Conventions

0 commit comments

Comments
 (0)