Add comprehensive test suite for service token authentication#2853
Add comprehensive test suite for service token authentication#2853jctanner wants to merge 1 commit intored-hat-data-services:masterfrom
Conversation
This commit adds a complete Robot Framework test suite to validate service account token authentication through the OpenShift AI Gateway. Test Coverage: - Infrastructure validation (gateway flags, RBAC, dedicated ServiceAccount) - End-to-end authentication flow with bearer tokens - Token validation via Kubernetes TokenReview API - User identity extraction and header forwarding - Security tests (invalid tokens, missing tokens) Architecture: - Echo service with kube-rbac-proxy sidecar pattern - HTTPRoute acceptance wait to ensure proper Envoy configuration - Proper RBAC scoping for test service accounts - Cleanup on teardown All 7 test cases pass successfully validating the service token auth feature. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: jctanner The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
| Create Test Service Account | ||
| [Documentation] Creates a test service account for token authentication with RBAC permissions | ||
| [Arguments] ${namespace}=opendatahub | ||
| ${rc} ${out}= Run And Return Rc And Output |
Check warning
Code scanning / Robocop
Local variable '{{ name }}' is overwritten before usage Warning test
|
|
||
| Log message=Invalid token was correctly rejected | ||
|
|
||
| Verify No Token Results In Auth Challenge |
Check warning
Code scanning / Robocop
Test case '{{ test_name }}' has too many keywords inside ({{ keyword_count }}/{{ max_allowed_count }}) Warning test
|
|
||
| Log message=Invalid token was correctly rejected | ||
|
|
||
| Verify No Token Results In Auth Challenge |
Check warning
Code scanning / Robocop
Test case '{{ test_name }}' is too long ({{ test_length }}/{{ allowed_length }}) Warning test
| [Documentation] Checks if HTTPRoute has Accepted condition set to True | ||
| [Arguments] ${route_name} ${namespace} | ||
| ${rc} ${status}= Run And Return Rc And Output | ||
| ... oc get httproute ${route_name} -n ${namespace} -o jsonpath='{.status.parents[0].conditions[?(@.type=="Accepted")].status}' |
Check warning
Code scanning / Robocop
Line is too long ({{ line_length }}/{{ allowed_length }}) Warning test
| [Documentation] Removes echo service deployment and related resources | ||
| [Arguments] ${namespace}=opendatahub | ||
| Log message=Removing echo service resources from ${namespace} | ||
| ${rc} ${out}= Run And Return Rc And Output |
Check warning
Code scanning / Robocop
Local variable '{{ name }}' is overwritten before usage Warning test
| ... oc delete -f ${ECHO_DEPLOYMENT_FILEPATH} -n ${namespace} --ignore-not-found=true | ||
| ${rc} ${out}= Run And Return Rc And Output | ||
| ... oc delete -f ${ECHO_SA_RBAC_FILEPATH} -n ${namespace} --ignore-not-found=true | ||
| ${rc} ${out}= Run And Return Rc And Output |
Check notice
Code scanning / Robocop
Variable '{{ name }}' is assigned but not used Note test
| ... oc delete -f ${ECHO_DEPLOYMENT_FILEPATH} -n ${namespace} --ignore-not-found=true | ||
| ${rc} ${out}= Run And Return Rc And Output | ||
| ... oc delete -f ${ECHO_SA_RBAC_FILEPATH} -n ${namespace} --ignore-not-found=true | ||
| ${rc} ${out}= Run And Return Rc And Output |
Check notice
Code scanning / Robocop
Variable '{{ name }}' is assigned but not used Note test
| [Documentation] Creates Gateway API HTTPRoute to expose echo service through gateway | ||
| [Arguments] ${namespace}=opendatahub | ||
| Log message=Creating HTTPRoute for echo service | ||
| ${rc} ${out}= Run And Return Rc And Output |
Check notice
Code scanning / Robocop
Variable '{{ name }}' is assigned but not used Note test
| ${rc} ${out}= Run And Return Rc And Output | ||
| ... oc apply -f ${ECHO_SA_FILEPATH} -n ${namespace} | ||
| Should Be Equal As Integers ${rc} 0 | ||
| ${rc} ${out}= Run And Return Rc And Output |
Check notice
Code scanning / Robocop
Variable '{{ name }}' is assigned but not used Note test
| [Documentation] Deploys echo service pod and service for testing | ||
| [Arguments] ${namespace}=opendatahub | ||
| Log message=Deploying echo service in ${namespace} namespace | ||
| ${rc} ${out}= Run And Return Rc And Output |
Check notice
Code scanning / Robocop
Variable '{{ name }}' is assigned but not used Note test
| *** Test Cases *** | ||
| Verify Service Token Auth Is Enabled On Gateway | ||
| [Documentation] Verifies that kube-auth-proxy deployment has service token validation enabled | ||
| [Tags] Smoke Tier1 RHOAIENG-XXXXX |
There was a problem hiding this comment.
if we want to run the tests as part of the Operator testing, we need to add the tag "Operator". The Smoke one can be removed
|
|
||
| Verify Dedicated ServiceAccount For Kube Auth Proxy | ||
| [Documentation] Verifies that kube-auth-proxy uses a dedicated ServiceAccount instead of default | ||
| [Tags] Security Tier1 RHOAIENG-XXXXX |
There was a problem hiding this comment.
if we want to run the tests as part of the Operator testing, we need to add the tag "Operator".
|
|
||
| Verify ClusterRoleBinding For TokenReview | ||
| [Documentation] Verifies that the ClusterRoleBinding for TokenReview API exists and is correctly configured | ||
| [Tags] Tier1 RHOAIENG-XXXXX |
There was a problem hiding this comment.
if we want to run the tests as part of the Operator testing, we need to add the tag "Operator".
|
|
||
| Verify Service Account Can Authenticate Via Token | ||
| [Documentation] End-to-end test: service account authenticates through gateway using bearer token | ||
| [Tags] Tier1 E2E RHOAIENG-XXXXX |
There was a problem hiding this comment.
if we want to run the tests as part of the Operator testing, we need to add the tag "Operator".
|
|
||
| Verify Service Account Token Has User Identity | ||
| [Documentation] Verifies that the authenticated token contains proper user identity information | ||
| [Tags] Tier1 RHOAIENG-XXXXX |
There was a problem hiding this comment.
if we want to run the tests as part of the Operator testing, we need to add the tag "Operator".
|
|
||
|
|
||
| *** Variables *** | ||
| ${TEST_NAMESPACE}= opendatahub |
There was a problem hiding this comment.
this should be removed and all references to it replaced with ${APPLICATIONS_NAMESPACE} to enable testing both on odh and rhoai
| subjects: | ||
| - kind: ServiceAccount | ||
| name: echo-service | ||
| namespace: opendatahub |
There was a problem hiding this comment.
Replace with ${APPLICATIONS_NAMESPACE} and process the file with Create File From Template before deploying
| config-file.yaml: | | ||
| authorization: | ||
| resourceAttributes: | ||
| namespace: opendatahub |
|
|
||
| Verify ClusterRoleBinding For TokenReview | ||
| [Documentation] Verifies that the ClusterRoleBinding for TokenReview API exists and is correctly configured | ||
| [Tags] Tier1 RHOAIENG-XXXXX |
There was a problem hiding this comment.
The tag should probably reference a real jira issue.
| containers: | ||
| # kube-rbac-proxy sidecar | ||
| - name: kube-rbac-proxy | ||
| image: quay.io/brancz/kube-rbac-proxy:v0.18.1 |
There was a problem hiding this comment.
We should use our rbac proxy build (this likely won't be mirrored on disconnected)
| - ALL | ||
| # echo application | ||
| - name: echo | ||
| image: ealen/echo-server:latest |
There was a problem hiding this comment.
This won't be mirrored on disconnected
|
@jctanner one thing I dislike about this approach is that it relies on kube-rbac-proxy config stored in this repo, not deployed by our operator. Is there any chance the operator-deployed config ever changes in a way that could break the functionality (you probably know much better than me)? Would it be possible to run this against real workload rather than a custom echo service? |
| Log message=Gateway response (HTTP ${http_code}): ${response} | ||
| RETURN ${response} | ||
|
|
||
| Get Gateway URL From Route |
There was a problem hiding this comment.
This will only work with OcpRoute ingressMode, right? We already have ${ODH_DASHBOARD_URL} which should be usable, or we could get the hostname from the gateway, not the route
There was a problem hiding this comment.
There's also Get Gateway URL in the EchoService.resource file, but that seems unused



http://issues.redhat.com/browse/RHOAIENG-47496
This commit adds a complete Robot Framework test suite to validate service account token authentication through the OpenShift AI Gateway.
Test Coverage:
Architecture:
All 7 test cases pass successfully validating the service token auth feature.