feat: 0.5.0 — config-driven RBAC seed + JWT tenant resolver#70
Merged
Conversation
devslab.kit.bootstrap.seed provisions starter permissions + roles (with grants) idempotently on boot, so consumers don't hand-create them in the console. Declare your domain permission codes and the roles that group them; the kit creates whatever is missing and grants it. - DevslabKitProperties.Bootstrap.Seed: permissions (list) + roles (map of code -> permission codes) - DevslabKitBootstrapRunner: seedDeclaredRbac() — idempotent, additive (never revokes/deletes); a permission referenced by a role is auto-created; permissions global, roles created in bootstrap tenant. Refactored shared ensurePermissionId/ensureRoleId helpers out of the admin bootstrap. - BootstrapSeedTests (sample-app, Testcontainers): declared permissions + roles + grants created, role-only permission auto-created, grants exact. - docs: configuration reference + bootstrap/access guides (EN/KO), CHANGELOG 0.5.0, version refs bumped to 0.5.0. Also corrected the tenant `jwt` resolver note in the configuration reference to "reserved, not yet shipped" (matches the tenancy guide). Verification: ./gradlew build BUILD SUCCESSFUL; BootstrapSeedTests 4/0/0; mkdocs build --strict clean.
`devslab.kit.tenant.resolver: jwt` now resolves the active tenant instead of failing fast at startup. It reads the kit-issued bearer token (which already carries a `tenant` claim) and falls back to `default-tenant-id` when there's no token — e.g. the login request itself. - JwtTenantResolver (tenant-core): reads `Authorization: Bearer`, parses via AuthTokenService, uses CurrentUser.tenantId(); same request-access pattern as HeaderTenantResolver. tenant-core gains compileOnly(identity-api) only — a consumer on another resolver never pulls identity. - TenantAutoConfiguration: `case JWT` wires it (AuthTokenService via ObjectProvider; clear error if the identity module is absent). - JwtTenantResolverTests (sample-app): wiring + resolves "acme" from a bearer token + falls back to "default" without one. - docs: tenancy + configuration `jwt` rows go from "reserved" to working, scoped to the kit's own HS256 token (external OAuth2/OIDC stays out of scope); CHANGELOG 0.5.0. Scope: this reads the kit's own token. Validating external OAuth2/OIDC tokens (JWKS, issuer, configurable claim) remains a separate future concern. Verification: ./gradlew build BUILD SUCCESSFUL; JwtTenantResolverTests 3/0/0, BootstrapSeedTests 4/0/0; mkdocs build --strict clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two features for 0.5.0, both lowering the "do it yourself" barrier.
1. Config-driven RBAC seed —
devslab.kit.bootstrap.seedShip starter permissions + roles so consumers don't hand-create them in the console. Declare your domain's permission codes and the roles that group them; the kit creates whatever is missing and grants it, idempotently on boot:
mirror). Change the config + redeploy → picked up.permissionsis auto-created.bootstrap.tenant-id.DevslabKitProperties.Bootstrap.Seed+DevslabKitBootstrapRunner.seedDeclaredRbac()(sharedensurePermissionId/ensureRoleIdhelpers factored out of the admin bootstrap).2. JWT tenant resolver —
resolver: jwtnow worksdevslab.kit.tenant.resolver: jwtpreviously threw at startup ("requires the not-yet-shipped oauth2-resource-server-starter"). It now resolves the active tenant from the kit-issued bearer token'stenantclaim (the token already carries it), falling back todefault-tenant-idwhen there's no token.JwtTenantResolver(tenant-core) — readsAuthorization: Bearer, parses viaAuthTokenService, usesCurrentUser.tenantId(); same request-access pattern asHeaderTenantResolver. tenant-core gainscompileOnly(identity-api)only — a consumer on another resolver never pulls identity.TenantAutoConfigurationcase JWTwires it (AuthTokenServiceviaObjectProvider; clear error if identity is absent).Tests (sample-app, Testcontainers)
BootstrapSeedTests(4): declared permissions + roles + grants created, role-only permission auto-created, grants exact.JwtTenantResolverTests(3): wiring, resolvesacmefrom a bearer token, falls back todefaultwithout one.Docs / release surfaces
jwtrow corrected from "reserved" → working.0.5.0(EN/KO); README + installation + tutorial + roadmap version refs bumped to0.5.0.Verification:
./gradlew build→ BUILD SUCCESSFUL; new tests 3/0/0 + 4/0/0, suite-wide failures=0 errors=0;mkdocs build --strictclean.KO 요약: 0.5.0 두 기능 — (1)
bootstrap.seed로 스타터 권한·역할을 부팅 시 멱등 시드(추가형, 역할 참조 권한 자동생성), (2)resolver: jwt가 이제 kit 자체 토큰의tenant클레임으로 실제 동작(무토큰 시 default 폴백; 외부 OIDC는 범위 밖). 테스트 7개 0/0, 전체 빌드 그린, docs strict clean.