organizations

Read the verdict of a configuration test (owner)

Redeem the ceremony's intent and report what a member's login would hit.

POST on a sub-resource despite being a read: the intent token is a bearer credential, and Zitadel already exposes it in a browser URL -- it must not travel in this service's request line as well.

Authenticates nobody -- no session, no account, no IdP link. Writes one thing, and only on a pass: verified_at / verified_template_id, which is what require_sso is gated on. An intent naming a template other than this connection's is refused rather than reported, so a redeemable intent obtained elsewhere cannot make a broken connection look tested.

Args: organization_id (int): The parent organization. payload (SsoTestResultRequest): The intent id and token from the return URL. db (AsyncSession): Request-scoped session. context (ActiveContext): Resolved caller.

Returns: SsoTestVerdictResponse: The verdict and the values it compared.

post/v1/organizations/{organization_id}/sso/test/result

Request

  • Base URL
    https://api.ethiack.com (the document declares no server; this is the origin it was published from)
  • Auth
    none declared

Path parameters

organization_idinteger required

Request body

intent_idstring required

The id query parameter from the return URL.

intent_tokenstring required

The token query parameter from the return URL. Never logged or stored server-side.

Response

Successful Response

passedboolean required

Whether a member's login would have been accepted. The one field a wizard should gate on; outcome says why when it is false.

outcome'passed' | 'ceremony_expired' | 'no_template_on_intent' | 'wrong_template' | 'no_expected_issuer' | 'no_assertion' | 'unreadable_assertion' | 'mismatched' | 'no_asserted_email' required

What a completed configuration test found.

Attributes: PASSED: The ceremony would have been accepted by the login path. NO_TEMPLATE_ON_INTENT: The redeemed intent names no IdP template. A broken ceremony rather than a configuration fault. WRONG_TEMPLATE: The intent names a template that is not this connection's. Refused rather than reported against this connection: an intent naming a template is not evidence it belongs to whoever redeems it. NO_EXPECTED_ISSUER: SAML answered, but no EntityID is stored to check it against, so nothing verified which provider signed. An administrator re-sending the customer's metadata records one. NO_ASSERTION: The connection expects an EntityID but the ceremony carried no assertion. UNREADABLE_ASSERTION: An assertion arrived whose Issuer could not be read. MISMATCHED: The assertion was signed by a different EntityID than the one stored -- usually the customer re-created their IdP. Repaired by an administrator re-sending their metadata, which re-derives the stored EntityID. NO_ASSERTED_EMAIL: Every tenancy check passed but no address could be read: none in Zitadel's claims (always the case for SAML) and none in the assertion -- no emailAddress NameID and no single email attribute (see :mod:._saml_email). Invisible without a test: a login refuses such an identity with nothing to tell the customer. CEREMONY_EXPIRED: The ceremony was never completed, or was completed too long ago. The one outcome that says nothing about the configuration -- the customer left the wizard open, which is the most predictable thing to happen in a wizard. Tell them to start again, not to look at their IdP.

template_idstring nullable

The Zitadel IdP template the ceremony ran against. Null on the three withholding outcomes above -- including wrong_template, where the intent did name one and it is deliberately not returned.

expected_issuerstring nullable

The SAML EntityID stored for this connection. Null for an OIDC connection, and null for a SAML one that stores none -- reported as no_expected_issuer only when the ceremony carried an assertion to compare it against.

asserted_issuerstring nullable

The EntityID that actually signed the assertion, when one could be read. Compared against expected_issuer; when they differ, re-send the customer's metadata through the admin IdP update so the stored EntityID tracks it again.

asserted_emailstring nullable

The address the provider released. Null on the three withholding outcomes above; on any other outcome it means none could be read -- for SAML, neither an emailAddress NameID nor an email attribute (email, emailaddress, mail, or the Entra claim URI). Logins refuse such an identity, and the customer has to release the address in one of those.

tester_link'linked' | 'already_linked' | 'other_address' | 'held_by_another' | 'not_linked'

What a passing test did about the tester's own account.

A passing ceremony is the strongest evidence this system ever gets that the person in front of it controls an identity at the organization's provider: they are signed in to Ethiack, and they have just completed a real sign-in at the provider in the same browser. So the tester's own account is linked to that identity -- keyed on the identifier the provider actually sent, not on an address, which also makes it work for a template asserting opaque persistent ids.

Only ever the tester, and only when the provider asserted the tester's own address. Anything else stays with POST .../sso/members/link.

Attributes: LINKED: This call linked the tester's account to the identity. ALREADY_LINKED: The identity already resolves to the tester's account. OTHER_ADDRESS: The provider asserted an address that is not the tester's -- typically an IT administrator testing with their own account. Linking it would let that person sign in as the tester, so nothing is linked. HELD_BY_ANOTHER: The identity already belongs to a different account. NOT_LINKED: Anything else: the tester has no Zitadel identity, is already linked to this provider under another identifier, may not link members (or that could not be checked), or Zitadel refused or was unreachable. The verdict stands either way; linking is a convenience on top of it.

Changes

No recorded changes to this operation across all 1 revision of this API.