Skip to content

Conversation

@simonhir
Copy link
Member

@simonhir simonhir commented Aug 6, 2025

Pull Request

Changes

  • Backend: replace deprecated permissions authorizations converter via user info endpoint with keyloak permissions endpoint

Reference

Issue: https://git.muenchen.de/ccse/refarch-security/-/issues/8

Checklist

Note: If some checklist items are not relevant for your PR, just remove them.

General

Code

  • Wrote code and comments in English
  • Added unit tests
  • Removed waste on branch (e.g. console.log), see code quality tooling

Development Stack

  • Checked functionality of Docker stack (if Docker stack was modified or images were changed)

Summary by CodeRabbit

  • Refactor
    • Switched authority retrieval to a permissions-based Keycloak converter and removed the deprecated user-info converter.
  • Chores
    • Replaced user-info config with permissions-uri and added permission cache lifetime; updated local/test configs and Keycloak migration and compose setup.
  • Tests
    • Renamed and updated tests to validate permissions-based authority retrieval.

✏️ Tip: You can customize this high-level summary in your review settings.

@simonhir simonhir self-assigned this Aug 6, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 6, 2025

Walkthrough

This PR replaces the deprecated UserInfoAuthoritiesConverter with KeycloakPermissionsAuthoritiesConverter, switches profile usage from "userinfo-authorities" to "keycloak-permissions", updates SecurityProperties (permissionsUri, permissionCacheLifetime), updates beans and wiring, adjusts tests and configs, and removes related Keycloak migration and volume mapping.

Changes

Cohort / File(s) Summary
Core Converter
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java, refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/UserInfoAuthoritiesConverter.java
Added KeycloakPermissionsAuthoritiesConverter (Converter<Jwt, Collection>) that POSTs to a permissions URI and caches results with Caffeine; removed deprecated UserInfoAuthoritiesConverter.
Bean & Wiring
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/AuthoritiesConverterConfiguration.java
Replaced bean userInfoAuthoritiesConverter with keycloakPermissionsAuthoritiesConverter; profile condition changed from userinfo-authorities to keycloak-permissions.
Security Config
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java
Replaced Optional field/type and control flow to use KeycloakPermissionsAuthoritiesConverter instead of UserInfoAuthoritiesConverter; updated docs/comments.
Properties
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityProperties.java
Removed userInfoUri; added permissionsUri (@NotBlank) and permissionCacheLifetime (Duration, default 60s).
Tests
refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java
Renamed/reworked tests to exercise POST permissions endpoint returning List<Map<String,String>>; added Spring test config and SecurityProperties wiring; adjusted mocks to ParameterizedTypeReference.
Application config
refarch-backend/src/main/resources/application-local.yml, refarch-backend/src/test/resources/application-test.yml
Replaced user-info-uri with permissions-uri and added client-id in test config; updated local/test YAML accordingly.
Infra / Migration
stack/docker-compose.yml, stack/keycloak/migration/permissions/P01_init_permissions.yml
Removed Keycloak plugins volume mount and removed client mapper block for userClientPermissionsAuthorities.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant SecurityConfig as Security Config
    participant Converter as KeycloakPermissionsAuthoritiesConverter
    participant Cache as Caffeine Cache
    participant Keycloak as Keycloak Endpoint

    Note over Client,Keycloak: Permission-fetch flow (POST, caching)
    Client->>SecurityConfig: request with JWT
    SecurityConfig->>Converter: convert(jwt)
    Converter->>Cache: lookup(jwt.subject)
    alt cache hit
        Cache-->>Converter: cached authorities
        Converter-->>SecurityConfig: authorities
    else cache miss
        Converter->>Keycloak: POST /permissions (form + Bearer JWT)
        alt success
            Keycloak-->>Converter: List of permission maps (rsid, rsname)
            Converter->>Converter: map to GrantedAuthority[]
            Converter->>Cache: store authorities (TTL)
            Converter-->>SecurityConfig: authorities
        else error
            Keycloak-->>Converter: error
            Converter-->>SecurityConfig: empty authorities
        end
    end
    SecurityConfig-->>Client: continue processing
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to cache TTL wiring and concurrency (permissionCacheLifetime).
  • Verify HTTP request form-encoding, headers, and ParameterizedTypeReference use.
  • Check beans/profile condition changes in AuthoritiesConverterConfiguration and SecurityConfiguration updates.
  • Review updated tests for proper mocking of RestTemplate.exchange signatures.

Poem

🐰 I hopped through code, swapped GET for POST,
To fetch permissions where the token goes most,
Caffeine tucks them in for a minute or two,
Hopping roles return — quick, clever, and new! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: introducing keycloak permissions authorities as a replacement for the deprecated user info endpoint approach.
Description check ✅ Passed The description includes most required sections: a concise summary of changes, a reference to the issue, and a completed checklist covering general, code, and development stack items.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/keycloak-permissions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added Template: Backend Issues regarding the backend template. Type: Feature The issue is an feature labels Aug 6, 2025
@simonhir simonhir changed the title feat/keycloak-permissions feat(backend): keycloak permissions authorities Aug 6, 2025
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative would be to merge both AuthoritiesConverter into one and allow enable/disable of the Keycloak permissions one.

@simonhir simonhir requested a review from rowe42 August 6, 2025 05:00
@simonhir
Copy link
Member Author

For Testing

rowe42
rowe42 previously approved these changes Nov 25, 2025
@simonhir simonhir requested a review from darenegade November 25, 2025 10:22
@simonhir simonhir marked this pull request as ready for review November 25, 2025 10:22
@simonhir simonhir requested a review from a team as a code owner November 25, 2025 10:22
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (3)

81-81: Replace assert keyword with JUnit's assertNotNull.

Java's assert keyword can be disabled at runtime with JVM flags, which would silently skip this check. Use JUnit's assertNotNull for consistent test behavior.

- assert authorities != null;
+ assertNotNull(authorities);

Also add the import if not present:

import static org.junit.jupiter.api.Assertions.assertNotNull;

102-102: Same issue: Replace assert with assertNotNull.

- assert authorities != null;
+ assertNotNull(authorities);

119-119: Same issue: Replace assert with assertNotNull.

- assert authorities != null;
+ assertNotNull(authorities);
♻️ Duplicate comments (2)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (2)

40-40: Hardcoded cache TTL should be configurable.

The 60-second cache expiry is hardcoded. Consider making this configurable via SecurityProperties.


85-85: Log injection risk with user-controlled data.

Logging the raw permissions response could allow log injection if the permissions endpoint returns malicious content. Consider sanitizing or limiting the logged output.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06049f8 and fc0b5f3.

⛔ Files ignored due to path filters (1)
  • stack/keycloak/plugins/authority-mapper-1.1.2-SNAPSHOT.jar is excluded by !**/*.jar
📒 Files selected for processing (10)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/AuthoritiesConverterConfiguration.java (1 hunks)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (1 hunks)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java (3 hunks)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityProperties.java (1 hunks)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/UserInfoAuthoritiesConverter.java (0 hunks)
  • refarch-backend/src/main/resources/application-local.yml (1 hunks)
  • refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (5 hunks)
  • refarch-backend/src/test/resources/application-test.yml (1 hunks)
  • stack/docker-compose.yml (0 hunks)
  • stack/keycloak/migration/permissions/P01_init_permissions.yml (0 hunks)
💤 Files with no reviewable changes (3)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/UserInfoAuthoritiesConverter.java
  • stack/keycloak/migration/permissions/P01_init_permissions.yml
  • stack/docker-compose.yml
🧰 Additional context used
🧬 Code graph analysis (1)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (1)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java (1)
  • RequiredArgsConstructor (27-88)
🔇 Additional comments (8)
refarch-backend/src/main/resources/application-local.yml (1)

57-58: Review comment is based on incorrect assumptions about the endpoint usage.

After examining the implementation, the original concerns are not valid:

  1. Endpoint URL is correct: KeycloakPermissionsAuthoritiesConverter makes a POST request to the configured URL with UMA 2.0 parameters (grant_type=urn:ietf:params:oauth:grant-type:uma-ticket and response_mode=permissions). The /protocol/openid-connect/token endpoint is Keycloak's standard endpoint for UMA 2.0 token requests—the correct choice for fetching permissions.

  2. Configuration is consistent: client-id and permissions-uri are properly defined in active profiles (local and test), while the base application.yml correctly omits the refarch.security section. The test profile intentionally uses a mock endpoint (http://localhost/permissions).

Likely an incorrect or invalid review comment.

refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java (1)

71-81: LGTM!

The authority converter selection logic correctly prioritizes KeycloakRolesAuthoritiesConverter over KeycloakPermissionsAuthoritiesConverter, with a graceful fallback to defaults.

refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/AuthoritiesConverterConfiguration.java (1)

16-27: LGTM!

The profile-based bean configuration ensures mutual exclusivity between the two converter types. The keycloak-permissions profile correctly activates only the permissions-based converter while defaulting to the roles-based converter otherwise.

refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (2)

71-91: Verify cache key strategy handles permission changes correctly.

Using jwt.getSubject() as the cache key means permission changes for a user won't be reflected until the cache entry expires (60 seconds). If permissions can change during a user's session (e.g., via admin action), consider including the token's iat (issued-at) claim in the cache key, or document this as expected behavior.


92-94: Error handling approach is sound.

The layered exception handling gracefully degrades to empty authorities on errors, which is a safe security default. The outer catch handles unexpected errors while fetchPermissions handles HTTP-specific failures.

refarch-backend/src/test/resources/application-test.yml (1)

12-18: LGTM!

Test configuration correctly updated to reflect the new permissionsUri property and includes appropriate placeholder values for testing.

refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (2)

36-39: LGTM!

The test configuration correctly combines @SpringBootTest for loading SecurityProperties with @ExtendWith(MockitoExtension.class) for mock support. The active profile ensures test-specific properties are loaded.


43-57: No issues found—properties correctly configured.

Verification of application-test.yml confirms that permissions-uri: http://localhost/permissions is explicitly configured, exactly matching the hardcoded PERMISSIONS_URI constant. The converter will correctly read this value from securityProperties, and the mock setup using eq(PERMISSIONS_URI) will match as expected. The test is correctly implemented.

Copy link
Member

@darenegade darenegade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please adjust documentation accordingly

Otherwise, it looks good.

darenegade
darenegade previously approved these changes Nov 26, 2025
@simonhir simonhir dismissed stale reviews from darenegade and rowe42 via d80d402 December 3, 2025 06:05
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java (1)

69-79: Converter precedence is clear; consider logging which converter is active (optional).

The fallback from roles-based authorities to the Keycloak permissions endpoint is straightforward and safe. For easier operational debugging, you could log which converter is actually being used:

-                            // authorities via keycloak roles scope
-                            if (keycloakRolesAuthoritiesConverter.isPresent()) {
-                                jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(
-                                        keycloakRolesAuthoritiesConverter.get());
-                            }
-                            // authorities via keycloak permissions endpoint
-                            else if (keycloakPermissionsAuthoritiesConverter.isPresent()) {
-                                jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(
-                                        keycloakPermissionsAuthoritiesConverter.get());
-                            } else {
+                            // authorities via keycloak roles scope
+                            if (keycloakRolesAuthoritiesConverter.isPresent()) {
+                                log.info("Configuring JwtAuthenticationConverter with KeycloakRolesAuthoritiesConverter.");
+                                jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(
+                                        keycloakRolesAuthoritiesConverter.get());
+                            }
+                            // authorities via keycloak permissions endpoint
+                            else if (keycloakPermissionsAuthoritiesConverter.isPresent()) {
+                                log.info("Configuring JwtAuthenticationConverter with KeycloakPermissionsAuthoritiesConverter.");
+                                jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(
+                                        keycloakPermissionsAuthoritiesConverter.get());
+                            } else {
                                 log.warn("No custom authority converter available, falling back to default.");
                             }

Purely a convenience improvement; behavior is already correct.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc0b5f3 and d80d402.

📒 Files selected for processing (4)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (1 hunks)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java (3 hunks)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityProperties.java (2 hunks)
  • refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze Java source files (./refarch-eai)
  • GitHub Check: Analyze Java source files (./refarch-backend)
  • GitHub Check: build (refarch-backend)
🔇 Additional comments (7)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityProperties.java (3)

8-8: Import for Duration is correct and scoped.

The added java.time.Duration import cleanly supports the new configuration field without introducing unused dependencies.


30-35: permissionsUri property and Javadoc look consistent with the new permissions flow.

The field is correctly marked @NotBlank, and the Javadoc now matches the permissions endpoint semantics and references KeycloakPermissionsAuthoritiesConverter appropriately.


36-40: permissionCacheLifetime default and validation are appropriate.

Using a Duration with a sane default of 60s and @NotNull provides safe, explicit cache control for permissions while remaining easily overridable via configuration.

refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (1)

52-62: LGTM: Constructor properly initializes dependencies.

The constructor correctly builds the RestTemplate and configures the Caffeine cache with the provided expiration lifetime from SecurityProperties.

refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (1)

44-44: Hardcoded PERMISSIONS_URI constant matches test configuration.

The test configuration in application-test.yml sets permissions-uri: http://localhost/permissions, which is loaded into SecurityProperties and returned by getPermissionsUri(). This matches the hardcoded PERMISSIONS_URI constant used in the RestTemplate stubs, so the mock will be invoked correctly.

The test is properly configured and does not have a URI mismatch issue. While using a hardcoded constant is a minor DRY violation, the suggested refactoring is not necessary for test correctness.

refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java (2)

24-25: Javadoc update correctly reflects the permissions-based converter.

The Javadoc now accurately mentions KeycloakPermissionsAuthoritiesConverter and its keycloak-permissions profile without labeling it deprecated, which aligns with the new permissions-based approach. No further changes needed here.


35-36: Optional injection for the permissions converter is consistent and clear.

Using Optional<KeycloakPermissionsAuthoritiesConverter> mirrors the existing pattern for the roles converter and keeps the configuration flexible. Just be aware that, given the current if/else if logic, if both beans are ever present, the roles converter will always be chosen; profiles/conditions should ensure that matches your intent.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (1)

82-82: Replace Java assert statements with JUnit assertNotNull() for test reliability.

The code uses Java assert statements at lines 82, 103, and 120 to check if authorities != null. These assertions rely on JVM assertions, which are disabled by default unless tests run with -ea. Since the file already imports JUnit assertions like assertEquals and assertTrue, replace all three assert authorities != null; statements with assertNotNull(authorities); to ensure the checks always execute and maintain consistency with the rest of the test suite.

♻️ Duplicate comments (1)
refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (1)

44-45: Align test URI stubbing with SecurityProperties to avoid duplication.

The converter calls fetchPermissions(securityProperties.getPermissionsUri(), ...), but the mocks stub restTemplate.exchange(eq(PERMISSIONS_URI), ...). If the configured URI ever diverges from the hard‑coded constant, the stubbing will no longer match. Prefer stubbing with eq(securityProperties.getPermissionsUri()) (and then you can drop or repurpose the PERMISSIONS_URI constant).

-        when(restTemplate.exchange(eq(PERMISSIONS_URI), eq(HttpMethod.POST), any(HttpEntity.class), any(ParameterizedTypeReference.class)))
+        when(restTemplate.exchange(eq(securityProperties.getPermissionsUri()), eq(HttpMethod.POST), any(HttpEntity.class), any(ParameterizedTypeReference.class)))
                 .thenReturn(new ResponseEntity<>(response, HttpStatus.OK));
...
-        when(restTemplate.exchange(eq(PERMISSIONS_URI), eq(HttpMethod.POST), any(HttpEntity.class), any(ParameterizedTypeReference.class)))
+        when(restTemplate.exchange(eq(securityProperties.getPermissionsUri()), eq(HttpMethod.POST), any(HttpEntity.class), any(ParameterizedTypeReference.class)))
                 .thenReturn(new ResponseEntity<>(response, HttpStatus.OK));

Also applies to: 75-76, 95-97

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d80d402 and 3f0e794.

📒 Files selected for processing (2)
  • refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (1 hunks)
  • refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverterTest.java (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (1)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/SecurityConfiguration.java (1)
  • RequiredArgsConstructor (27-88)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze Java source files (./refarch-backend)
  • GitHub Check: Analyze Java source files (./refarch-eai)
  • GitHub Check: build (refarch-backend)
🔇 Additional comments (2)
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java (2)

73-80: Verify that caching solely by JWT subject is correct for your permission model.

Authorities are cached under jwt.getSubject() only; if permissions can differ for the same subject based on other dimensions (e.g. clientId, tenant, realm) within the cache lifetime, this could serve stale or cross‑context authorities. If such variation exists, include the additional dimensions in the cache key (e.g. composite key of subject + clientId/tenant) or shorten the TTL accordingly.

Also applies to: 93-93


101-107: Robust, type‑safe permissions mapping looks good.

Using ParameterizedTypeReference<List<Map<String, String>>> for RestTemplate.exchange plus asAuthorities filtering out null/empty rsname values avoids SimpleGrantedAuthority errors and gives a clean, type‑safe mapping from the Keycloak response to authorities.

Also applies to: 124-126

Comment on lines +52 to +61
public KeycloakPermissionsAuthoritiesConverter(final SecurityProperties securityProperties, final RestTemplateBuilder restTemplateBuilder) {
this(
securityProperties,
restTemplateBuilder.build(),
new CaffeineCache(
AUTHENTICATION_CACHE_NAME,
Caffeine.newBuilder()
.expireAfterWrite(securityProperties.getPermissionCacheLifetime())
.ticker(Ticker.systemTicker())
.build()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider bounding the Caffeine cache size to avoid unbounded growth.

The cache currently uses only expireAfterWrite(permissionCacheLifetime); with many distinct sub values inside that TTL window, entries can grow without an upper bound. Consider adding a reasonable maximumSize(...) (or making it configurable) to cap memory usage for long‑lived services.

🤖 Prompt for AI Agents
In
refarch-backend/src/main/java/de/muenchen/refarch/configuration/security/KeycloakPermissionsAuthoritiesConverter.java
around lines 52 to 61, the Caffeine cache is built with only
expireAfterWrite(...) which allows unbounded growth; update the cache builder to
include a maximumSize(...) cap (make value configurable via SecurityProperties,
e.g., getPermissionCacheMaxSize() with a sensible default) so the cache cannot
grow indefinitely, validate/configure the property in SecurityProperties and use
that value when building the Caffeine.newBuilder() chain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Template: Backend Issues regarding the backend template. Type: Feature The issue is an feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants