Repository navigation
Live suite: scute-python against a real Scute API (pytest -m live) - #2
Merged
Merged
Conversation
tests/live runs scute-python against the v2 API with no mocks, one file per area: app, sign-in (email and SMS OTP with test identities), tokens, MFA, users, signing in as a user, authorization (with local decisions matching the server, and the FastAPI and Flask glue on real sessions), agents, the auth MCP server and the decision log. Where the SDK has no API (sign-in, MFA, policy and roles, filter, snapshot, access requests, agents, properties, auth MCP, decision log) the tests call the HTTP API with httpx and say so. Each run names what it makes live-<runid> and deletes it at the end, also on failure. Tokens, keys and codes are wrapped so a failing assert never prints them. Deselected by default (addopts -m "not live"), so pytest and CI are unchanged. Without SCUTE_LIVE_* credentials (or .sdk-live/python.env next to the checkout) every live test is skipped with one reason and the run exits 0.
…xfails First real run against v2 (v21). Suite fixes: the FastAPI test module can't use postponed annotations (FastAPI reads the route signatures at runtime and the auth object is local), and the refresh test is split so the refresh itself is checked apart from verifying the refreshed token locally. Confirmed API bugs, marked xfail(strict=True) with the finding as the reason: - a refreshed access token carries aid = the app's internal UUID, so tokens.verify refuses it as wrong_app - sessions.list and sessions.revoke get 401 Not authorized with the secret key alone (the endpoint also wants a user session) - users.find_by_identifier creates an active user for an unused identifier, even without credentials 48 passed, 4 xfailed; cleanup leaves no users, roles, resources, agents or properties behind and puts the settings back.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
tests/live: scute-python against a real Scute API (the v2 deployment), with no mocks. It's off in the normal run and in CI (addopts = -m "not live"), sopytestand the CI job are unchanged.One file per area:
remote=True.actclaim,authz_context), list, stop, and "not while impersonating" refused inside the session.decide_locallymatching the server over a 10-case matrixoutside_task), a step-up through the human steps, properties (read a secret; an ES256 signature checked against the JWKS), a budget of 2 pausing the agent on the 3rd action, suspend and resume.scute_identify,scute_submit_code,scute_check, then the backend's conversation lookup and check.The SDK has no API for some of this: the sign-in itself, MFA, policy and roles, filter, the snapshot, access requests, agents, properties, the auth MCP and the decision log. Those tests call the HTTP API with httpx and say so. There's no Python agent harness yet.
A few more details:
live-<runid>and deleted at the end, also when tests fail.tests/live/test_support.pychecks the suite's own helpers offline (RFC 6238 vectors, masking, the env file, cleanup order). It runs in CI.How to run
Without credentials every live test is skipped with one line and the run exits 0.
Result against scute-api-v2 (v21)
48 passed, 4 xfailed.
ruffandmypy --strict tests/liveare clean. After the run the app has no users, roles, resources, permissions, agents or properties, and its authz and MFA settings are back as they were.Findings
These are confirmed against the live API and marked
xfail(strict=True)with the finding as the reason. A fix shows up as an unexpected pass.aid= the app's public id (apitoken_session.rb:57). A token fromPOST /v1/auth/:app_id/tokens/refreshcarriesaid= the app's internal UUID (TokenSession#jwt_session,token_session.rb:300).GET current_user: 200).scute.tokens.verifyrefuses it withInvalidToken, reasonwrong_app, so every refreshed session fails local verification.test_a_refreshed_token_verifies_locally.scute.sessions.listandscute.sessions.revokedon't work with the secret key.GET /v1/:app_id/users/:id/sessionsanswers 401{"error": "Not authorized"}, with noerror_code.DELETE /v1/:app_id/users/:id/sessions/:session_idanswers the same.GET /v1/:app_id/users/:id.authorize_access_request!, which wants a user session inX-Authorization(apisessions_controller.rb:6-8).test_lists_sessions,test_revokes_a_session.scute.users.find_by_identifiercreates users.Nonewhen nobody uses the identifier. In factGET /v1/auth/:app_id/users?identifier=<unused>answers 200 and creates an active user (the count for that email went from 0 to 1).api_base_controller.rb:282).test_find_by_identifier_is_none_for_nobody.Checked, not bugs (behaviour pinned in tests or noted)
users.create(meta=...)with a key the app hasn't declared as a user meta field answers 200, withuser_meta_errors: [{key, message: "Invalid value for <key>"}], and the meta isn't saved.users.update(user_meta=...)answers 422{"errors": [...]}. The SDK doesn't raise on the create. So the README'smeta=examples need the field declared in the dashboard first (the app secret can't declare it). Pinned bytest_meta_needs_declared_fields.tokens.verifywith an app id whose JWKS can't be fetched raisesAPIError(404,app_not_found), notInvalidToken. A misconfiguration surfaces as an API error, which seems right. No test.Not covered
users.invite: it sends a real magic-link email, and test identities only cover OTP codes.mfa_reverify_minutes(minimum 5). The suite passes the verification anyway.