5.6 KiB
5.6 KiB
VCTP Auth Design TODO (LDAP + JWT)
1. Goal
Add authentication and authorization to VCTP for sensitive endpoints, using the LDAP bind + JWT pattern from cbs2 as a reference, adapted to VCTP's net/http architecture.
2. Reference Findings from cbs2
2.1 Where auth lives in cbs2
- Login handler:
/tmp/cbs2/server/handler/auth.go - JWT middleware:
/tmp/cbs2/server/handler/middlewares.go - Token utilities:
/tmp/cbs2/utils/token/token.go - LDAP bind + group lookup:
/tmp/cbs2/internal/ldap/ldap.go - Route protection split (public vs protected):
/tmp/cbs2/server/router/router.go - Settings fields for LDAP/JWT:
/tmp/cbs2/internal/settings/settings.goand/tmp/cbs2/src/cbs.yml
2.2 Pattern to reuse
- LDAP username/password bind for authentication.
- LDAP group membership check for authorization at login.
- Signed JWT access token with expiry.
- Middleware that validates
Authorization: Bearer <token>. - Router-level grouping for protected routes.
2.3 Things to improve (do not copy as-is)
- Avoid hardcoded fallback JWT secret (present in
cbs2middleware). - Avoid logging sensitive token/key values.
- Avoid weak/ambiguous claim model; use explicit issuer/audience/subject/exp/iat.
- Keep strict method/endpoint policy in one place instead of ad-hoc checks.
3. Proposed VCTP Auth Architecture
3.1 New packages/modules
internal/auth/ldap.go
- LDAP setup/connection helpers.
AuthenticateAndFetchGroups(username, password) ([]string, error).
internal/auth/jwt.go
- JWT issue and verify.
- Claims struct with:
sub(username)roles(derived roles)groups(optional raw LDAP groups)iss,aud,iat,exp,nbf,jti
server/middleware/auth.go
RequireAuth(...)for token validation.RequireRole(...)for endpoint authorization.- Context injection for user identity and roles.
server/handler/auth.go
POST /api/auth/login- Optional
GET /api/auth/mefor debugging/whoami.
3.2 Route protection model
Define a central policy map in router startup (single source of truth):
- Public (no auth):
/assets/*,/favicon*,/swagger*(optional decision),/(optional decision)
- Authenticated read-only (viewer role):
/vcenters*,/snapshots/*,/vm/trace,/api/report/*,/metrics(optional decision)
- Privileged write/admin (admin role):
/api/snapshots/*mutating endpoints/api/vcenters/cache/rebuild/api/encrypt- legacy mutating endpoints (
/api/event/*,/api/import/vm,/api/inventory/vm/*,/api/cleanup/*)
- Debug endpoints (
/debug/pprof/*):- disabled by default via config
- if enabled, require admin
4. VCTP Settings Additions
Add under settings: in internal/settings/settings.go and src/vctp.yml:
auth_enabled: falseauth_mode: "disabled"(disabled|optional|required)auth_jwt_signing_key: ""(base64-encoded, required when auth enabled)auth_token_lifespan_minutes: 120auth_jwt_issuer: "vctp"auth_jwt_audience: "vctp-api"auth_clock_skew_seconds: 60ldap_groups: []ldap_bind_address: ""ldap_base_dn: ""ldap_trust_cert_file: ""ldap_disable_validation: falseldap_insecure: falseenable_pprof: false
5. Role Mapping
Use LDAP group DN mapping to roles (config-driven):
auth_group_role_mappingsmap/list, e.g.:- group DN ->
admin - group DN ->
viewer
- group DN ->
Default behavior:
- No mapped group: deny login.
- Multiple matches: union roles.
6. API Contract
6.1 Login
POST /api/auth/login
- Request:
{ "username": "...", "password": "..." } - Success:
{ "access_token": "...", "expires_at": <unix>, "token_type": "Bearer" } - Failure:
401with generic message (no user/group leakage)
6.2 Auth header
Authorization: Bearer <jwt>
6.3 Error behavior
- Missing/invalid token:
401 - Valid token but insufficient role:
403
7. Rollout Plan
Phase 1: Foundation
- Implement settings fields and validation.
- Implement LDAP and JWT services.
- Add
/api/auth/login. - Add unit tests for token generation/validation and LDAP auth abstraction.
Phase 2: Middleware + policy
- Add auth middleware for
net/http. - Protect sensitive routes via central policy map.
- Keep
auth_mode=optionalinitially for safe rollout.
Phase 3: Enforce + harden
- Switch production to
auth_mode=required. - Gate/disable pprof by config.
- Add structured audit logs for auth events.
- Update Swagger security docs and README.
8. Validation and Tests
- Unit tests
- JWT: expired token, wrong signature, wrong issuer/audience, clock skew.
- Role extraction and mapping.
- Integration tests (handler/middleware)
- Unauthenticated access blocked on protected endpoints.
- Viewer can read but cannot mutate.
- Admin can mutate.
- Regression checks
- Existing legacy endpoint gating (
enable_legacy_api) still behaves correctly after auth layering.
9. Open Decisions
- Should
/metricsrequire auth in your deployment? No there is no need for auth for this endpoint - Should UI pages (
/,/vcenters,/snapshots/*,/vm/trace) require login or stay public? These should stay public - Should Swagger UI be public, authenticated, or disabled in production? These should stay public
- Do you want short-lived access tokens only, or access + refresh token flow? Short lived access tokens please, 2 hours is good enough
10. Implementation Notes for VCTP
- Reuse
cbs2LDAP flow shape, but avoid its fallback secret behavior. - Keep all secret material redacted in logs.
- Validate required auth settings at startup when
auth_enabled=true. - Prefer fail-closed: if auth is enabled and misconfigured, abort startup.