Skip to content

Conversation

@omertuc
Copy link
Member

@omertuc omertuc commented Aug 26, 2025

See commit message

Summary by CodeRabbit

  • New Features
    • Added role-based access control: users mapped to "redhat_employee" can query models, manage conversations, send feedback, view metrics and info; sensitive actions are explicitly denied for others.
  • Bug Fixes
    • Added a pre-check in the query flow to obtain an OCM token with a clear error message on failure.
  • Chores
    • Updated base container image reference and bumped lightspeed-stack submodule.

@openshift-ci openshift-ci bot requested review from eranco74 and maorfr August 26, 2025 12:00
@coderabbitai
Copy link

coderabbitai bot commented Aug 26, 2025

Walkthrough

Updates Containerfile.assisted-chat base image (tag + digest), removes build-time patching steps, advances lightspeed-stack submodule, adds an OCM token pre-check in scripts/query.sh’s new-conversation path, and adds JWT role mapping plus authorization access rules in template.yaml.

Changes

Cohort / File(s) Summary of changes
Base image & Dockerfile cleanup
Containerfile.assisted-chat
Replaced base image tag/digest: from dev-20250814-7a531cb@sha256:90deb575... to dev-20250826-913b5a6@sha256:09d6e222.... Removed root/patch-related build steps (USER root, microdnf install patch, curl
Submodule bump
lightspeed-stack
Updated submodule pointer from 053d49fb6e19...913b5a6b2887.... No other repo-local code changes shown.
OCM token pre-check
scripts/query.sh
In the new-conversation path added a pre-check to fetch an OCM token; on failure prints "Failed to get OCM token for query" and exits 1 before model retrieval/selection.
JWT role mapping & authorization rules
template.yaml
Added role_rules mapping (jsonpath "$.realm_access.roles[*]" contains "redhat:employees" → redhat_employee) and authorization.access_rules including redhat_employee allow list (get_models, query, streaming_query, get_conversation, list_conversations, delete_conversation, feedback, get_metrics, info) and explicit nobody deny list for sensitive actions. Inline comments added.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant Q as scripts/query.sh
  participant O as OCM
  participant L as Lightspeed API

  U->>Q: Start new conversation
  Q->>O: Request OCM token
  alt Token fetched
    O-->>Q: Token
    Q->>L: get_available_models (with token)
    L-->>Q: Models
    Q->>L: query/streaming_query (with token, selected model)
    L-->>Q: Response
  else Token failure
    Q-->>U: "Failed to get OCM token for query" (exit 1)
  end
Loading
sequenceDiagram
  autonumber
  participant C as Client
  participant G as Gateway/API
  participant J as JWT Role Mapper
  participant A as Authorization Engine
  participant S as Lightspeed Service

  C->>G: Request with JWT
  G->>J: Extract roles (jsonpath $.realm_access.roles[*])
  J-->>G: Internal roles (e.g., redhat_employee)
  G->>A: Check access_rules for action
  alt Allowed (redhat_employee)
    A-->>G: Permit
    G->>S: Perform action
    S-->>G: Result
    G-->>C: Success
  else Denied (nobody or not listed)
    A-->>G: Deny
    G-->>C: Forbidden
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

Possibly related PRs

Suggested labels

lgtm, ok-to-test

Suggested reviewers

  • eranco74
  • maorfr
  • keitwb

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b33e3eb and e248a72.

📒 Files selected for processing (4)
  • Containerfile.assisted-chat (1 hunks)
  • lightspeed-stack (1 hunks)
  • scripts/query.sh (1 hunks)
  • template.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • lightspeed-stack
🚧 Files skipped from review as they are similar to previous changes (3)
  • template.yaml
  • scripts/query.sh
  • Containerfile.assisted-chat
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Collaborator

@maorfr maorfr left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci
Copy link

openshift-ci bot commented Aug 26, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: maorfr, omertuc

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
scripts/query.sh (1)

29-31: /v1/models now requires auth; add Authorization header and handle HTTP errors.

You pre-check OCM login, but get_available_models doesn’t send the bearer token nor validate HTTP status. With auth enabled, this will 401 and later jq/fzf will fail under set -e. Include the header and return an error on non-2xx.

-get_available_models() {
-    curl --silent --show-error -X 'GET' "${BASE_URL}/v1/models" -H 'accept: application/json'
-}
+get_available_models() {
+    local tmpfile status body
+    tmpfile=$(mktemp)
+    status=$(curl --silent --show-error --output "$tmpfile" --write-out "%{http_code}" \
+        -H "Authorization: Bearer ${OCM_TOKEN}" \
+        -H 'accept: application/json' \
+        -X 'GET' "${BASE_URL}/v1/models")
+    body=$(cat "$tmpfile")
+    rm "$tmpfile"
+    if ! good_http_response "$status"; then
+        echo "Error: Failed to fetch models (HTTP $status)"
+        echo "Response: $body"
+        return 1
+    fi
+    echo "$body"
+}
🧹 Nitpick comments (2)
scripts/query.sh (1)

223-223: Nit: error message scope.

The message reads "Failed to get OCM token for query" but this block is for model listing during new conversation. Consider clarifying to "for model listing" for consistency with history/listing blocks.

template.yaml (1)

174-190: Clarify the comment placement to avoid misreading the action scope.

The commented-out wildcard example sits between actions: and the rest of the un-commented actions. It reads as if the actions following it belong to the wildcard block, while they actually continue the redhat_employee allowlist. Move the example above the block or reword to avoid confusion.

-          - role: redhat_employee
-            actions:
-            - get_models
-          # Temporarily we only want redhat employees to be able to use the service,
-          # uncomment when we want to allow all authenticated users
-          # - role: "*"
-          #   actions:
-            - query
+          # Temporarily we only want redhat employees to be able to use the service.
+          # When we want to allow all authenticated users, add a new rule:
+          #   - role: "*"
+          #     actions:
+          #       - get_models
+          #       - query
+          #       - streaming_query
+          #       ...
+          - role: redhat_employee
+            actions:
+            - get_models
+            - query
             - streaming_query
             - get_conversation
             - list_conversations
             - delete_conversation
             - feedback
             - get_metrics
             - info
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d839c04 and b33e3eb.

📒 Files selected for processing (4)
  • Containerfile.assisted-chat (1 hunks)
  • lightspeed-stack (1 hunks)
  • scripts/query.sh (1 hunks)
  • template.yaml (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
scripts/query.sh (1)
utils/ocm-token.sh (1)
  • get_ocm_token (9-25)
⏰ 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). (1)
  • GitHub Check: Red Hat Konflux / assisted-chat-saas-main-on-pull-request
🔇 Additional comments (3)
Containerfile.assisted-chat (1)

2-3: Manual verification required: confirm tag⇄digest match
Automated checks in this environment couldn’t resolve the dev-20250826-969904b tag’s digest. Please verify locally that it matches sha256:5582703f6220f0668ea465c66e81f2a5a425437e1a12b4419c8a61e930a11aad before merging:

• Using skopeo (requires skopeo + jq):

skopeo inspect docker://quay.io/lightspeed-core/lightspeed-stack:dev-20250826-969904b \
  | jq -r '.Digest'

• Or using Docker CLI:

docker pull quay.io/lightspeed-core/lightspeed-stack:dev-20250826-969904b
docker inspect --format='{{index .RepoDigests 0}}' quay.io/lightspeed-core/lightspeed-stack:dev-20250826-969904b

Ensure the returned digest equals the pinned value above.

template.yaml (2)

56-58: Auth defaults to false; ensure it’s enabled where this template is applied.

PR intent is to restrict usage to Red Hat employees. With LIGHTSPEED_SERVICE_AUTH_ENABLED defaulting to "false", deployments that don’t override this param won’t enforce JWT/RBAC. Confirm the parameter is set to "true" in the environments that consume this template (e.g., via Qontract params or overlays).

Also applies to: 154-155


168-173: Please verify the exact role claim emitted by your Identity Provider

I only found the plural form (“redhat:employees”) in template.yaml (line 171) and no occurrences of the singular form in the codebase. We can’t confirm from code alone which variant your SSO will emit.

• Confirm with your SSO/Keycloak what exact string (and casing) appears under $.realm_access.roles[*] in the JWT at runtime.
• If you discover tokens carrying “redhat:employee” instead of (or in addition to) “redhat:employees”, add a second role_rules entry for the singular form:

           jwt_configuration:
             user_id_claim: ${USER_ID_CLAIM}
             username_claim: ${USERNAME_CLAIM}
             role_rules:
               - jsonpath: "$.realm_access.roles[*]"
                 operator: "contains"
                 value: "redhat:employees"
                 roles: ["redhat_employee"]
+              - jsonpath: "$.realm_access.roles[*]"
+                operator: "contains"
+                value: "redhat:employee"
+                roles: ["redhat_employee"]

Optionally, if your template engine supports regex or case-insensitive matching, you could consolidate both in one rule to avoid duplication.

lightspeed-stack Outdated
@@ -1 +1 @@
Subproject commit 053d49fb6e19c63cd51e77816f7c7cb5907d0f93
Subproject commit 969904b4aef1dbe4379b279effe065237233a687
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Submodule bump acknowledged; please verify downstream integration (image, auth rules, script pre-check).

The pointer change itself is fine. Given this bump gates access to Red Hat employees via the new authorization features, please validate that all consuming artifacts in this PR match the bumped commit and intended policies.

Run this script from repo root to confirm consistency across the PR (submodule pointer, base image tag/digest, template auth config, and the OCM token pre-check in scripts/query.sh):

If helpful, I can add a smoke test plan to validate:

  • Unauthorized user receives a clear 403 with a human-friendly message.
  • A JWT with realm_access.roles containing “redhat:Employees” maps to role “redhat_employee” and can: query, stream, list/get/delete own conversations, and submit feedback.
  • “get_config” and all “other_conversations” operations are denied to non-admins.

🏁 Script executed:

#!/bin/bash
set -euo pipefail

EXPECTED_SUBMOD_SHA=969904b4aef1dbe4379b279effe065237233a687
EXPECTED_IMAGE_TAG='dev-20250826-969904b'
EXPECTED_IMAGE_DIGEST='sha256:5582703f6220f0668ea465c66e81f2a5a425437e1a12b4419c8a61e930a11aad'

echo "Verifying submodule pointer…"
actual_sha="$(git ls-tree HEAD lightspeed-stack | awk '{print $3}')"
echo "lightspeed-stack @ ${actual_sha}"
test "$actual_sha" = "$EXPECTED_SUBMOD_SHA" || { echo "ERROR: Submodule SHA mismatch"; exit 1; }

echo "Verifying Containerfile base image tag/digest…"
fd -a 'Containerfile.assisted-chat' -t f | while read -r f; do
  rg -n "${EXPECTED_IMAGE_TAG}" "$f" >/dev/null || { echo "ERROR: Tag not updated in $f"; exit 1; }
  rg -n "${EXPECTED_IMAGE_DIGEST}" "$f" >/dev/null || { echo "ERROR: Digest not updated in $f"; exit 1; }
done

echo "Verifying authorization and role mapping in template.yaml…"
fd -a 'template.yaml' -t f | while read -r f; do
  rg -n 'authorization:\s*$' "$f" -C2 || { echo "ERROR: authorization block missing in $f"; exit 1; }
  rg -n '\$\.realm_access\.roles\[\*\]' "$f" >/dev/null || { echo "ERROR: role_rules jsonpath missing in $f"; exit 1; }
  rg -n 'redhat:Employees' "$f" >/dev/null || { echo "ERROR: expected role value missing in $f"; exit 1; }
  rg -n 'roles:\s*\[\s*redhat_employee\s*\]' "$f" >/dev/null || { echo "ERROR: role mapping to redhat_employee missing in $f"; exit 1; }
  rg -n 'access_rules:' "$f" >/dev/null || { echo "ERROR: access_rules missing in $f"; exit 1; }
done

echo "Verifying OCM token pre-check in scripts/query.sh…"
fd -a 'scripts/query.sh' -t f | while read -r f; do
  rg -n 'Failed to get OCM token for query' "$f" >/dev/null || { echo "ERROR: OCM token pre-check message missing in $f"; exit 1; }
done

echo "All checks passed ✅"

Length of output: 1694


Mismatch in template.yaml role value causing verification failure

The automated verification script failed when validating the role value in template.yaml. The file currently uses a lowercase role identifier, which does not match the expected value:

  • File: template.yaml
  • Current line:
    value: "redhat:employees"
  • Expected:
    value: "redhat:Employees"

Please update the role value to "redhat:Employees" (note the uppercase “E”) so that it aligns with the authorization rules and allows the downstream checks to pass. Once updated, rerun the provided script to confirm:

# After updating template.yaml:
bash verify-integration.sh

If you’d like, I can also help draft a smoke-test plan to ensure:

  • Unauthorized users receive a clear 403 response.
  • JWTs with realm_access.roles containing “redhat:Employees” map correctly to redhat_employee.
  • Only the intended operations are permitted for this role (query, stream, list/get/delete own conversations, submit feedback).
  • Non-admins are denied “get_config” and “other_conversations” operations.
🤖 Prompt for AI Agents
In lightspeed-stack template.yaml around line 1, the role value is using the
wrong case ("redhat:employees"); update the value to "redhat:Employees" (capital
E) so it matches the expected authorization rule; save the file and rerun bash
verify-integration.sh to confirm the verification passes.

Comment on lines +221 to +226

if ! get_ocm_token; then
echo "Failed to get OCM token for query"
return 1
fi

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Top-level 'return' will abort with a confusing bash error; use 'exit 1' instead.

This block runs at the top level (not inside a function). Using 'return' here emits "bash: return: can only return' from a function or sourced script" and exits due to set -e, but the error is noisy and misleading. Replace with exit 1`.

-    if ! get_ocm_token; then
-        echo "Failed to get OCM token for query"
-        return 1
-    fi
+    if ! get_ocm_token; then
+        echo "Failed to get OCM token for model listing"
+        exit 1
+    fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ! get_ocm_token; then
echo "Failed to get OCM token for query"
return 1
fi
if ! get_ocm_token; then
echo "Failed to get OCM token for model listing"
exit 1
fi
🤖 Prompt for AI Agents
In scripts/query.sh around lines 221 to 226, the script uses "return 1" at
top-level which causes a confusing "can only `return' from a function or sourced
script" error; replace the top-level "return 1" with "exit 1" so the script
terminates cleanly when get_ocm_token fails, ensuring consistent exit behavior
under set -e.

@maorfr
Copy link
Collaborator

maorfr commented Aug 26, 2025

need to remove the patch?

Copy link
Collaborator

@eranco74 eranco74 left a comment

Choose a reason for hiding this comment

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

/lgtm

@eranco74
Copy link
Collaborator

need to remove the patch?

Not yet, LSC need to bump llama-stack first

@maorfr
Copy link
Collaborator

maorfr commented Aug 26, 2025

Not yet, LSC need to bump llama-stack first

at least the LSC patch, not the llama-stack patch.

jwt_configuration:
user_id_claim: ${USER_ID_CLAIM}
username_claim: ${USERNAME_CLAIM}
role_rules:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's move this to a parameter so we can tweak it from app interface

Copy link
Member Author

Choose a reason for hiding this comment

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

What kind of parameter?

operator: "contains"
value: "redhat:employees"
roles: ["redhat_employee"]
authorization:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same

@omertuc
Copy link
Member Author

omertuc commented Aug 26, 2025

Let's merge the bump first, then tweak the configs / parameters later

@eranco74
Copy link
Collaborator

/retest

1 similar comment
@omertuc
Copy link
Member Author

omertuc commented Aug 26, 2025

/retest

Bump lightspeed-stack submodule to include the authorization changes
from lightspeed-core/lightspeed-stack#356

Use the new authorization features to restrict access to the
assisted-chat service to, for now, Red Hat employees only.

In the future we can open this up to all authenticated users.

Also bumped to a version that no longer requires the patching of
llama-stack / lightspeed-stack to support postgres SSL, so removed the
patching steps from the Containerfile.
@eranco74
Copy link
Collaborator

/lgtm

@openshift-ci openshift-ci bot added the lgtm label Aug 26, 2025
@eranco74
Copy link
Collaborator

/test eval-test

@eranco74
Copy link
Collaborator

/retest

@openshift-ci
Copy link

openshift-ci bot commented Aug 27, 2025

@omertuc: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/eval-test e248a72 link true /test eval-test

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@eranco74 eranco74 merged commit 0d821d3 into rh-ecosystem-edge:main Aug 27, 2025
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants