<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="0" failures="5" skipped="0" tests="73" time="542.145" timestamp="2026-06-08T23:05:08.380132+00:00" hostname="maas-group-test-hg7wv-e2e-maas-openshift-pod"><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="0.112" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="0.146" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="0.107" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="0.137" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_non_admin_cannot_access_other_users_keys" time="0.103" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_own_keys" time="0.268" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="0.033" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="0.109" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_within_expiration_limit" time="0.035" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_at_expiration_limit" time="0.035" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_exceeds_expiration_limit" time="0.034" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_without_expiration" time="0.034" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_with_short_expiration" time="0.035" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.111" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_invalid_api_key_rejected" time="0.025" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_no_auth_header_rejected" time="0.023" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_revoked_api_key_rejected" time="2.127" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_chat_completions" time="0.034" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_double_revoke_returns_404" time="0.105" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.034" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="0.171" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="0.201" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="0.307" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cronjob_exists_and_configured" time="0.104" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cleanup_networkpolicy_exists" time="0.105" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_create_ephemeral_key" time="0.109" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.510" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="9.226" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="19.128" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="19.260" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_pending_subscription" time="19.259"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_api_keys.TestAPIKeySubscriptionPhases object at 0x7fdbc6a5a160&gt;

    def test_create_key_for_pending_subscription(self):
        """API key creation succeeds for Pending subscription."""
        ns = _ns()
        subscription_name = "e2e-apikey-pending-sub"
        auth_name = "e2e-apikey-pending-auth"
        sa_name = "e2e-apikey-pending-sa"
    
        try:
            oc_token = _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)
            sa_user = _sa_to_user(sa_name, namespace=MODEL_NAMESPACE)
    
            _create_test_auth_policy(auth_name, MODEL_REF, users=[sa_user])
            _create_test_subscription(subscription_name, MODEL_REF, users=[sa_user])
            _wait_reconcile(seconds=10)
    
            # Patch to Pending phase
            patch_data = {
                "status": {
                    "phase": "Pending",
                    "conditions": [{
                        "type": "Ready",
                        "status": "False",
                        "reason": "Pending",
                        "message": "Reconciliation in progress",
                        "lastTransitionTime": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
                    }],
                }
            }
    
            cmd = [
                "kubectl", "patch", "maassubscription", subscription_name,
                "-n", ns, "--type=merge", "--subresource=status",
                "-p", json.dumps(patch_data)
            ]
            result = subprocess.run(cmd, capture_output=True, text=True)
            assert result.returncode == 0, f"Failed to patch: {result.stderr}"
    
            cr = _get_cr("maassubscription", subscription_name, namespace=ns)
            phase = cr.get("status", {}).get("phase")
            assert phase == "Pending", f"Expected Pending, got {phase}"
    
            # Create API key (should succeed)
&gt;           api_key = _create_api_key(
                oc_token,
                name="pending-sub-test",
                subscription=subscription_name
            )

test/e2e/tests/test_api_keys.py:1334: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFyN0tVWXdJejQ3Nm5ZbXpobmdJOWZiMXNWc2piR25NclpOekQ4Q0VMNWcifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...zCWuZkRhVkP9hstcKXogap9OPqsTXm8rkZDfMzT9b9g9HmGoD981DFAGS2gaqraCyuUCG7cZKDL9lQl8p5ItxRcRzw7U1OHgipeTMDoS4-xAR92LynOhkg'
name = 'pending-sub-test', subscription = 'e2e-apikey-pending-sub'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:246: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_reject_key_for_unreconciled_subscription" time="22.981"><failure message="AssertionError: Expected 400 for unreconciled subscription, got 500: &#10;assert 500 == 400&#10; +  where 500 = &lt;Response [500]&gt;.status_code">self = &lt;test_api_keys.TestAPIKeySubscriptionPhases object at 0x7fdbc6a5a4c0&gt;

    def test_reject_key_for_unreconciled_subscription(self):
        """
        API key creation is rejected for unreconciled subscription (empty phase).
    
        Note: Temporarily sets webhook failurePolicy to Ignore to allow creating
        resources while controller is down, then restores to Fail.
        """
        ns = _ns()
        subscription_name = "e2e-apikey-unreconciled-sub"
        auth_name = "e2e-apikey-unreconciled-auth"
        sa_name = "e2e-apikey-unreconciled-sa"
        webhook_name = "maas-validating-webhook-configuration"
    
        try:
            # Create service account and get token
            oc_token = _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)
            sa_user = _sa_to_user(sa_name, namespace=MODEL_NAMESPACE)
    
            # Temporarily set webhook failurePolicy to Ignore
            # This allows creates to succeed when controller/webhook is unavailable
            # Find webhook indices dynamically by name to avoid brittleness
            result = subprocess.run(
                ["oc", "get", "validatingwebhookconfiguration", webhook_name, "-o", "json"],
                capture_output=True, text=True, check=True
            )
            webhook_config = json.loads(result.stdout)
            patch_ops = []
            for idx, webhook in enumerate(webhook_config.get("webhooks", [])):
                if webhook.get("name") in ["vmaassubscription.kb.io", "vmaasauthpolicy.kb.io"]:
                    patch_ops.append({"op": "replace", "path": f"/webhooks/{idx}/failurePolicy", "value": "Ignore"})
    
            subprocess.run(
                ["oc", "patch", "validatingwebhookconfiguration", webhook_name,
                 "--type=json", "-p", json.dumps(patch_ops)],
                capture_output=True, text=True, check=True
            )
    
            # Scale down controller to prevent reconciliation
            _scale_controller_down()
    
            # Create resources (webhook unavailable but Ignore policy allows creates)
            _create_test_auth_policy(auth_name, MODEL_REF, users=[sa_user])
            _create_test_subscription(subscription_name, MODEL_REF, users=[sa_user])
    
            # Verify subscription is unreconciled (empty phase)
            cr = _get_cr("maassubscription", subscription_name, namespace=ns)
            phase = cr.get("status", {}).get("phase", "")
            assert phase == "", f"Expected empty phase, got: {phase}"
            log.info("✅ Subscription is unreconciled (empty phase)")
    
            # Try to create API key (should fail with 400)
            response = requests.post(
                f"{_maas_api_url()}/v1/api-keys",
                headers={
                    "Authorization": f"Bearer {oc_token}",
                    "Content-Type": "application/json"
                },
                json={
                    "name": "unreconciled-sub-test",
                    "subscription": subscription_name
                },
                timeout=TIMEOUT,
                verify=TLS_VERIFY,
            )
    
&gt;           assert response.status_code == 400, \
                f"Expected 400 for unreconciled subscription, got {response.status_code}: {response.text}"
E               AssertionError: Expected 400 for unreconciled subscription, got 500: 
E               assert 500 == 400
E                +  where 500 = &lt;Response [500]&gt;.status_code

test/e2e/tests/test_api_keys.py:1414: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="10.186" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="0.207" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_subscription_namespace_visible_to_api" time="8.518" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_another_namespace_not_visible_to_api" time="22.313" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_maas_subscription_namespace" time="23.951" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_another_namespace" time="29.859" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_auth_policy_model_ref" time="30.854" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_subscription_model_ref" time="30.753" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_injected_identity_headers_ignored" time="0.083" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="0.072" /><testcase classname="test.e2e.tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.075" /><testcase classname="test.e2e.tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.064" /><testcase classname="test.e2e.tests.test_negative_security.TestAuthPolicyRemoval" name="test_authpolicy_deletion_revokes_access" time="5.017" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="0.981" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="0.638" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="0.172" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_subscription_rejected_in_unlabeled_namespace" time="6.004" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_authpolicy_rejected_in_unlabeled_namespace" time="5.850" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.080" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_no_auth_gets_401" time="0.021" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_invalid_token_gets_403" time="0.022" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_wrong_group_gets_403" time="0.025" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_uses_highest_priority_subscription" time="0.309" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="0.070" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="0.253" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_subscribed_user_gets_200" time="0.033" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_auth_pass_no_subscription_gets_403" time="16.408" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_rate_limit_exhaustion_gets_429" time="25.587" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_models_endpoint_exempt_from_rate_limiting" time="25.261" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleSubscriptionsPerModel" name="test_user_in_one_of_two_subscriptions_gets_200" time="8.381" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_two_auth_policies_or_logic" time="16.740"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_subscription.TestMultipleAuthPoliciesPerModel object at 0x7fdbc6926190&gt;

    def test_two_auth_policies_or_logic(self):
        """Two auth policies for the premium model with OR logic: user matching either gets access."""
        ns = _ns()
        try:
            # Create a 2nd auth policy that allows system:authenticated (user's actual group)
            _apply_cr({
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSAuthPolicy",
                "metadata": {"name": "e2e-premium-sa-auth", "namespace": ns},
                "spec": {
                    "modelRefs": [{"name": PREMIUM_MODEL_REF, "namespace": MODEL_NAMESPACE}],
                    "subjects": {"groups": [{"name": "system:authenticated"}]},
                },
            })
            # Create a subscription for system:authenticated on premium model
            _apply_cr({
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSSubscription",
                "metadata": {"name": "e2e-premium-sa-sub", "namespace": ns},
                "spec": {
                    "owner": {"groups": [{"name": "system:authenticated"}]},
                    "modelRefs": [{"name": PREMIUM_MODEL_REF, "namespace": MODEL_NAMESPACE, "tokenRateLimits": [{"limit": 100, "window": "1m"}]}],
                },
            })
            _wait_reconcile()
    
            # Key must be minted for the premium subscription
&gt;           api_key = _create_api_key(
                _get_cluster_token(),
                name=f"e2e-premium-sa-{uuid.uuid4().hex[:8]}",
                subscription="e2e-premium-sa-sub",
            )

test/e2e/tests/test_subscription.py:720: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFyN0tVWXdJejQ3Nm5ZbXpobmdJOWZiMXNWc2piR25NclpOekQ4Q0VMNWcifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...8U8pneKEE3GWJ2i0P-4rgbYsEfenGBF6TMl0k_aBEt4dByx91VDbSmtsL_WHtNXm2sWdqfUtbLRWJI96WM3WClH-F25Cb0PPQ3DkmR_QulG8LtcJoFSeLQ'
name = 'e2e-premium-sa-75a7a95d', subscription = 'e2e-premium-sa-sub'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:246: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_delete_one_auth_policy_other_still_works" time="44.891" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_subscription_rebuilds_trlp" time="8.501" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_trlp_persists_during_multi_subscription_deletion" time="33.328" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_last_subscription_denies_access" time="8.475" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_unconfigured_model_denied_by_gateway_auth" time="0.475" /><testcase classname="test.e2e.tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="19.049" /><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_authpolicy_managed_false_prevents_update" time="20.305" /><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_trlp_managed_false_prevents_update" time="18.512" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="9.697"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_subscription.TestE2ESubscriptionFlow object at 0x7fdbc6a7b250&gt;

    def test_e2e_with_both_access_and_subscription_gets_200(self):
        """
        Full E2E test: Create MaaSModelRef, MaaSAuthPolicy, and MaaSSubscription from scratch.
        API key with both access and subscription should get 200 OK.
    
        This is the comprehensive test that validates the complete E2E flow including
        MaaSModelRef creation and reconciliation. Other tests use existing models for speed.
        """
        ns = _ns()
        model_ref = "e2e-test-model-success"
        auth_policy_name = "e2e-test-auth-success"
        subscription_name = "e2e-test-subscription-success"
        sa_name = "e2e-sa-success"
    
        try:
            # Create service account and get OC token for maas-api
            oc_token = _create_sa_token(sa_name, namespace=ns)
            sa_user = _sa_to_user(sa_name, namespace=ns)
    
            # Create model and governance resources together so the model
            # can reach Ready (requires MaaSSubscription + MaaSAuthPolicy).
            _create_test_maas_model(model_ref)
            _create_test_auth_policy(auth_policy_name, model_ref, users=[sa_user])
            _create_test_subscription(subscription_name, model_ref, users=[sa_user])
    
            endpoint = _wait_for_maas_model_ready(model_ref, timeout=120)
    
            # Extract path from endpoint (e.g., https://maas.../llm/facebook-opt-125m-simulated -&gt; /llm/facebook-opt-125m-simulated)
            model_path = urlparse(endpoint).path
    
            # API key bound to this subscription at mint (inference does not send x-maas-subscription)
&gt;           api_key = _create_api_key(
                oc_token, name=f"{sa_name}-key", subscription=subscription_name
            )

test/e2e/tests/test_subscription.py:1320: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFyN0tVWXdJejQ3Nm5ZbXpobmdJOWZiMXNWc2piR25NclpOekQ4Q0VMNWcifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...so-J-nNXaYwVe12rCacEIgBuPbk-eV_yFLW5_1WVjdbJMtzNyDRil9cgjnI8wjRXtkGCuANccxInd4UmsmnTddeAMmK5Wsnu6i4zb0YRtaHxWz6NyRWUXQ'
name = 'e2e-sa-success-key', subscription = 'e2e-test-subscription-success'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:246: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_access_but_no_subscription_gets_403" time="9.186"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_subscription.TestE2ESubscriptionFlow object at 0x7fdbc6a7bc40&gt;

    def test_e2e_with_access_but_no_subscription_gets_403(self):
        """
        Test: User with access (MaaSAuthPolicy) but not in any subscription gets 403.
        Uses existing model (facebook-opt-125m-simulated) for faster execution.
    
        Note: We temporarily remove simulator-subscription to ensure the test user
        has auth but no matching subscriptions.
        """
        ns = _ns()
        auth_policy_name = "e2e-test-auth-no-sub"
        sa_name = "e2e-sa-no-sub"
    
        # Snapshot existing subscription to restore later
        original_sim = _snapshot_cr("maassubscription", SIMULATOR_SUBSCRIPTION)
    
        try:
            # Create service account and get OC token for maas-api
            oc_token = _create_sa_token(sa_name, namespace=ns)
            sa_user = _sa_to_user(sa_name, namespace=ns)
    
            # Create auth policy for this specific user
            _create_test_auth_policy(auth_policy_name, MODEL_REF, users=[sa_user])
    
            # Bind simulator subscription on the key while the CR still exists, then remove it
&gt;           api_key = _create_api_key(
                oc_token,
                name=f"{sa_name}-key",
                subscription=SIMULATOR_SUBSCRIPTION,
            )

test/e2e/tests/test_subscription.py:1360: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFyN0tVWXdJejQ3Nm5ZbXpobmdJOWZiMXNWc2piR25NclpOekQ4Q0VMNWcifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...46s8MSplcYUcES5n-a0-_LpKB3rrI8iPb90G1cn_RkNSAArrzLNDHRcBLEehhZQPCk3vmnBYTZiOfi_X4tXt6jzgen2L2WAHb2C2PR9sdf9ycfe9kOiL9A'
name = 'e2e-sa-no-sub-key', subscription = 'simulator-subscription'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:246: RuntimeError</failure></testcase></testsuite></testsuites>