Override Points
IAM follows one contract everywhere: every capability is opt-out with a safe default, and every default is a bean your application can replace. Define your own bean of the seam type and IAM’s default steps aside.
The seams
Section titled “The seams”| Seam | Default | Replace it when |
|---|---|---|
PermissionChecker |
full three-tier resolution | you need custom decision logic or an external PDP |
PermissionCache |
Caffeine in-memory | Hazelcast, Infinispan, your cache fabric |
IamTenantDataSourceRegistry |
properties-backed pools | dynamic tenant fleets, vault-managed credentials |
SecurityFilterChain |
IAM’s JWT chain | your app owns the chain, composes IAM’s filters |
| Repository ports (16) | Spring Data JPA adapters | alternative persistence for any entity |
RateLimitStore |
in-memory | distributed limiting |
Example: your own cache
Section titled “Example: your own cache”@Configurationclass AccessConfig { @Bean fun permissionCache(hz: HazelcastInstance): PermissionCache = object : PermissionCache { override fun get(tenantId: UUID, userId: UUID): ResolvedPermissions? = /* ... */ override fun put(tenantId: UUID, userId: UUID, permissions: ResolvedPermissions) { /* ... */ } override fun evict(tenantId: UUID, userId: UUID) { /* ... */ } override fun evictTenant(tenantId: UUID) { /* ... */ } }}Example: dynamic tenant databases
Section titled “Example: dynamic tenant databases”@Beanfun tenantDataSourceRegistry(vault: VaultTemplate): IamTenantDataSourceRegistry = IamTenantDataSourceRegistry { tenantId -> pools.computeIfAbsent(tenantId) { buildPool(vault.credentialsFor(it)) } }(fun interface — a lambda is a valid registry.)
Example: swap persistence for one entity
Section titled “Example: swap persistence for one entity”Every repository sits behind a port. Replace the adapter for a single aggregate without touching the rest:
@Bean@Primaryfun auditLogRepositoryPort(mongo: MongoTemplate): AuditLogRepositoryPort = MongoAuditLogAdapter(mongo) // audit goes to Mongo; everything else stays JPAConfig-level opt-outs (no code)
Section titled “Config-level opt-outs (no code)”Everything big also has a flag: iam.enabled, iam.cache.enabled, iam.rate-limit.enabled,
iam.audit.enabled, iam.oauth2.enabled, iam.two-factor.enabled,
iam.multi-tenancy.enabled, iam.resources.enabled. Disabled never means “missing bean” —
it means a no-op implementation, so your code never null-checks a capability.