Skip to content

fix: restore report owner verification on Keycloak by using SA roles#279

Open
rhartuv wants to merge 7 commits into
RHEcosystemAppEng:mainfrom
rhartuv:keycloack-audit-fix
Open

fix: restore report owner verification on Keycloak by using SA roles#279
rhartuv wants to merge 7 commits into
RHEcosystemAppEng:mainfrom
rhartuv:keycloack-audit-fix

Conversation

@rhartuv

@rhartuv rhartuv commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix POST /api/v1/reports/failed owner verification on Keycloak (external-idp): stop using instanceof JsonWebToken to tell humans from service accounts.
  • Detect service accounts via configured roles (exploitiq.security.service-account-roles), so ownership checks work across OpenShift OAuth and Keycloak.
  • Cover SA bypass in ReportServiceAuditTest.

Problem

requiresOwnerVerification() treated any JWT principal as a service account. That works on OpenShift OAuth (only SAs use JWTs), but on Keycloak both humans and SAs use JWTs — so owner verification was skipped for everyone, and any authenticated user could mark another user's reports as failed.

Fix

Replace JWT-type coupling with a role check against configured service-account roles (@ConfigProperty, outside the exploit-iq.* AppConfig mapping so native builds do not resolve ${NAMESPACE} at image-build time):

  • OpenShift: system:serviceaccounts:${NAMESPACE}:exploit-iq-sa, ...:pipeline
  • Keycloak: exploitiq-api-access
    Human callers still require metadata.user to match the actor; SA-role callers skip ownership checks.

Jira

@vbelouso

vbelouso commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@rhartuv

rhartuv commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@zvigrinberg zvigrinberg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hi @rhartuv

The idea is good, and it should work as expected.
Just one configuration trick, that will improve a lot the configuration maintainability .

Thank you.

@zvigrinberg zvigrinberg Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv Use here property expression that will expand the property values into the list here ( instead of hard-coding the service account names one after another), in order to prevent maintenance burden of keeping the values aligned, which is error prone

quarkus.http.auth.policy.role-policy.roles-allowed=exploit-iq-view,exploit-iq-prodsec,exploit-iq-admin,${exploitiq.security.service-account-roles}


# Service-account roles used to skip report owner verification (OIDC-provider agnostic).
# Outside exploit-iq.* AppConfig mapping so native builds do not bake unresolved ${NAMESPACE}.
# Keep in sync with the SA entries in role-policy.roles-allowed above.

@zvigrinberg zvigrinberg Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv This is redundant and just maintenance burden which is tend to be error prone
[See above] (#279 (comment))

@zvigrinberg zvigrinberg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv
1 Final comment, PTAL.

Thank you.

quarkus.rest-client.github.headers.User-Agent=exploit-iq
quarkus.rest-client.exploit-iq.url=https://exploit-iq:8080/generate
%dev.quarkus.rest-client.exploit-iq.url=http://localhost:26466/generate
%dev.NAMESPACE=local-dev

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv It's already defined here in development profile.

Comment on lines +144 to +145
exploitiq.security.service-account-roles=system:serviceaccounts:${NAMESPACE:local-dev}:exploit-iq-sa,system:serviceaccounts:${NAMESPACE:local-dev}:pipeline,exploitiq-api-access

@zvigrinberg zvigrinberg Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv You don't need the default for NAMESPACE env var expansion, as it's already defined in the development profile property entry in the configuration file for development purposes.
On cluster environments the NAMESPACE env var is always populated using the K8 Downward API' fieldRef facility/feature. ( it's getting the metadata.namespace value of the pod injected into this env var).

Suggested change
exploitiq.security.service-account-roles=system:serviceaccounts:${NAMESPACE:local-dev}:exploit-iq-sa,system:serviceaccounts:${NAMESPACE:local-dev}:pipeline,exploitiq-api-access
exploitiq.security.service-account-roles=system:serviceaccounts:${NAMESPACE}:exploit-iq-sa,system:serviceaccounts:${NAMESPACE}:pipeline,exploitiq-api-access

See #279 (comment)

zvigrinberg
zvigrinberg previously approved these changes Jul 22, 2026

@zvigrinberg zvigrinberg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv LGTM Approved

@zvigrinberg
zvigrinberg dismissed their stale review July 22, 2026 10:18

Found former blocking bug


# Service-account roles (OIDC-provider agnostic): used for HTTP auth and to skip report owner verification.
# Outside exploit-iq.* AppConfig mapping so native builds do not bake unresolved ${NAMESPACE}.
exploitiq.security.service-account-roles=system:serviceaccounts:${NAMESPACE}:exploit-iq-sa,system:serviceaccounts:${NAMESPACE}:pipeline,exploitiq-api-access

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv Just found out now, this is a regression, it causing 403 on environment.

Suggested change
exploitiq.security.service-account-roles=system:serviceaccounts:${NAMESPACE}:exploit-iq-sa,system:serviceaccounts:${NAMESPACE}:pipeline,exploitiq-api-access
exploitiq.security.service-account-roles=system:serviceaccount:${NAMESPACE}:exploit-iq-sa,system:serviceaccount:${NAMESPACE}:pipeline,exploitiq-api-access

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry, my bad. Fixing

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv There was a more deep cause (beyond that) , I've fixed it...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will rebase after you merge

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@rhartuv It merged ( #281) , you can rebase.

afterwards, Kindly test on your cluster environment ( eiq-rht ) using the temporary pr image tag, to see it goes well with a simple invocation of an analysis ( DOD -> agent-> client communication is valid and works as expected, the result sent correctly from agent to client , and shown in UI).

Thank you!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

afterwards, Kindly test on your cluster environment ( eiq-rht ) using the temporary pr image tag, to see it goes well with a simple invocation of an analysis ( DOD -> agent-> client communication is valid and works as expected, the result sent correctly from agent to client , and shown in UI).

Done

@rhartuv
rhartuv requested a review from zvigrinberg July 22, 2026 10:31
@rhartuv
rhartuv force-pushed the keycloack-audit-fix branch from 37e27d9 to cb6b1dc Compare July 26, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants