Skip to content

[FEATURE][AUTH]: Just-in-Time (JIT) access and temporary privilege elevation#3292

Open
yiannis2804 wants to merge 6 commits intoIBM:mainfrom
yiannis2804:feature/issue-2227-jit-access
Open

[FEATURE][AUTH]: Just-in-Time (JIT) access and temporary privilege elevation#3292
yiannis2804 wants to merge 6 commits intoIBM:mainfrom
yiannis2804:feature/issue-2227-jit-access

Conversation

@yiannis2804
Copy link
Copy Markdown
Contributor

🔗 Related Issue

Closes #2227


Sweng Group 5

📝 Summary

Implements Just-in-Time (JIT) access and temporary privilege elevation to enforce least-privilege principles (FedRAMP AC-6, HIPAA). Instead of granting standing elevated access, users request temporary roles with a justification, an admin approves or rejects the request, and access automatically expires after the specified duration.

New files:

  • mcpgateway/db.pyJITGrant SQLAlchemy model with full lifecycle tracking
  • mcpgateway/schemas.py — Pydantic schemas for request, approve, reject, revoke, and response
  • mcpgateway/services/jit_service.pyJITService with create, approve, reject, revoke, and expire_grants methods
  • mcpgateway/routers/jit.py — REST API router with 7 endpoints
  • mcpgateway/alembic/versions/a1b2c3d4e5f6_add_jit_grants_table.py — Alembic migration for jit_grants table
  • docs/docs/manage/jit.md — Full feature documentation with API examples, config reference, and compliance table
  • tests/unit/mcpgateway/services/test_jit_service.py — 17 unit tests at 97% coverage

Modified files:

  • mcpgateway/main.py — JIT router registered alongside RBAC router
  • mcpgateway/config.py — 6 new JIT config settings (JIT_ENABLED, JIT_MAX_DURATION_HOURS, JIT_DEFAULT_DURATION_HOURS, JIT_REQUIRE_JUSTIFICATION, JIT_REQUIRE_APPROVAL, JIT_APPROVAL_TIMEOUT_HOURS)

API endpoints added:

  • POST /jit — Request temporary elevated access
  • GET /jit — List all grants (admin only)
  • GET /jit/mine — List current user's own grants
  • GET /jit/{id} — Get grant by ID
  • POST /jit/{id}/approve — Approve a pending grant (admin only)
  • POST /jit/{id}/reject — Reject a pending grant (admin only)
  • POST /jit/{id}/revoke — Revoke an active grant (self or admin)

Grant lifecycle: pending → active → expired (auto) or pending → rejected or active → revoked


🏷️ Type of Change

  • Feature / Enhancement

🧪 Verification

Check Command Status
Lint suite make lint ✅ Passed
Unit tests make test ✅ 17/17 passed, 0 failures
Coverage ≥ 80% make coverage ✅ 97% on jit_service.py
Package verify make verify ✅ 10/10 Mascarpone

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • Tests added/updated for changes
  • Documentation updated (docs/docs/manage/jit.md)
  • No secrets or credentials committed

📓 Notes

  • Alembic migration a1b2c3d4e5f6 creates the jit_grants table with indexes on requester_email, status, expires_at, and created_at
  • The expire_grants() method in JITService is designed to be called by a scheduler (e.g. APScheduler) to auto-expire active grants — scheduler integration can be added as a follow-up
  • Break-glass emergency access and notification system (email/Slack/webhook) are deferred to follow-up issues per the original issue scope

@crivetimihai crivetimihai added this to the Release 1.2.0 milestone Feb 27, 2026
@crivetimihai crivetimihai changed the title Feature/issue 2227 jit access [FEATURE][AUTH]: Just-in-Time (JIT) access and temporary privilege elevation Feb 27, 2026
@crivetimihai crivetimihai added enhancement New feature or request security Improves security COULD P3: Nice-to-have features with minimal impact if left out; included if time permits api REST API Related item labels Feb 27, 2026
@crivetimihai
Copy link
Copy Markdown
Member

Thanks @yiannis2804. Comprehensive implementation of JIT access for #2227 — good that it includes the full lifecycle (request, approve, reject, revoke, auto-expire). A few things to check:

  1. Verify the Alembic migration down_revision points to the current head (cd mcpgateway && alembic heads)
  2. Ensure the new endpoints have deny-path regression tests per project security invariants (unauthenticated, wrong team, insufficient permissions)
  3. The JITGrant model additions to db.py should be reviewed for consistency with existing ORM patterns

…vation (IBM#2227)

- Add JITGrant SQLAlchemy model to db.py with full lifecycle tracking
- Add JIT schemas (request, approve, reject, revoke, response) to schemas.py
- Add JITService with create, approve, reject, revoke, expire_grants methods
- Add JIT REST API router with endpoints: POST /jit, GET /jit, GET /jit/mine,
  GET /jit/{id}, POST /jit/{id}/approve, POST /jit/{id}/reject, POST /jit/{id}/revoke
- Register JIT router in main.py alongside RBAC router
- Add Alembic migration a1b2c3d4e5f6 for jit_grants table
- Add 17 unit tests with 97% coverage

Closes IBM#2227

Signed-off-by: yiannis2804 <yiannis2804@gmail.com>
Signed-off-by: yiannis2804 <yiannis2804@gmail.com>
- Add jit_enabled, jit_max_duration_hours, jit_default_duration_hours
- Add jit_require_justification, jit_require_approval, jit_approval_timeout_hours

Signed-off-by: yiannis2804 <yiannis2804@gmail.com>
Signed-off-by: yiannis2804 <yiannis2804@gmail.com>
- Fix Alembic down_revision to point to latest head (b2d9c6e4f1a7)
- Add ORM relationships to JITGrant model for consistency with existing patterns
- Add router-level deny-path tests (unauthenticated, 403, 404, invalid status)
- Fix token scoping middleware mock in test_main.py to prevent 403 interference
- Fix metrics settings conftest to override DB_METRICS_RECORDING_ENABLED=false
- Fix test_tool_service_coverage mock fields and plugin_manager for pydantic validation
- Rebase onto upstream/main

Signed-off-by: yiannis2804 <yiannis2804@gmail.com>
@yiannis2804 yiannis2804 force-pushed the feature/issue-2227-jit-access branch from 1cfa77b to cc195e9 Compare February 27, 2026 12:32
@yiannis2804
Copy link
Copy Markdown
Contributor Author

Hi @crivetimihai, thanks for the review! I've addressed all three points:

  1. Alembic down_revision — Updated to point to the current head (b2d9c6e4f1a7 - add_explicit_team_and_token_permissions). Verified with alembic heads showing a single head.

  2. Deny-path regression tests — Added tests/unit/mcpgateway/routers/test_jit_router.py with 21 tests covering unauthenticated access, wrong user (403), insufficient permissions, invalid status transitions (400), and nonexistent resources (404).

  3. JITGrant ORM consistency — Added requester, approver, and revoker relationships to EmailUser with proper foreign_keys and backref declarations, consistent with the existing Role/UserRole patterns in db.py. Also added section comment # Request details to match the existing comment style.

…M#2227)

- Convert jit_service tests from asyncio.get_event_loop() to pytest.mark.asyncio
- Fix log_aggregator tests: set _use_sql_percentiles and enabled directly on instance
- Fix metrics_buffer/rollup tests: use usefixtures reset_metrics_settings
- Fix dcr_service test: update client_name assertion to MCP Gateway
- Fix prompt_service test: patch get_plugin_manager directly to return None
- Fix tool_service_coverage test: add missing mock fields and patch _plugin_manager
- Update services conftest: add patch_is_postgresql autouse fixture

Signed-off-by: yiannis2804 <yiannis2804@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api REST API Related item COULD P3: Nice-to-have features with minimal impact if left out; included if time permits enhancement New feature or request security Improves security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE][AUTH]: Just-in-time (JIT) access and temporary privilege elevation

2 participants