SamlApi
extends ManagementSupport
in package
A tenant's SAML 2.0 identity provider (CONTRACT §29): the registry of service providers, the import of an SP's metadata into a *draft* registration (never a write), and the lifecycle of the IdP signing credential. The protocol itself -- single sign-on, single logout, the IdP metadata document -- is browser and SP-to-IdP surface under /saml/v2/{tenant_id}, an SP's own SAML library speaks to it, and it is not in this registry.
The saml namespace handle (CONTRACT.md §27.2), reached as $client->management()->saml().
Every method here goes through the one shared ManagementTransport, so §3 CSRF, the §4
cookie jar, the §5 tenant header, §6 TLS, §16 retry and §19 telemetry apply without this
class doing anything to opt in (§27.8).
Table of Contents
Methods
- __construct() : mixed
- createServiceProvider() : SamlServiceProvider
- `POST /api/v1/tenants/{tenant_id}/saml/service-providers`
- deleteServiceProvider() : void
- `DELETE /api/v1/tenants/{tenant_id}/saml/service-providers/{sp_id}`
- forTenant() : static
- A COPY of this handle scoped to `$tenantId` (§27.4 rule 3). See {@see self::inOrg()} for why it copies.
- getIdp() : SamlIdpInfo
- `GET /api/v1/tenants/{tenant_id}/saml/idp`
- getServiceProvider() : SamlServiceProvider
- `GET /api/v1/tenants/{tenant_id}/saml/service-providers/{sp_id}`
- inOrg() : static
- A COPY of this handle scoped to `$orgId` (§27.4 rule 3).
- issueIdpCredential() : SamlIdpCredential
- `POST /api/v1/tenants/{tenant_id}/saml/idp-credentials`
- listIdpCredentials() : array<int, SamlIdpCredential>
- `GET /api/v1/tenants/{tenant_id}/saml/idp-credentials`
- listServiceProviders() : Page<string|int, SamlServiceProvider>
- `GET /api/v1/tenants/{tenant_id}/saml/service-providers`
- parseSpMetadata() : SamlSpMetadataDraft
- `POST /api/v1/tenants/{tenant_id}/saml/parse-sp-metadata`
- promoteIdpCredential() : SamlIdpCredentialPromotion
- `POST /api/v1/tenants/{tenant_id}/saml/idp-credentials/{credential_id}/promote`
- retireIdpCredential() : SamlIdpCredential
- `POST /api/v1/tenants/{tenant_id}/saml/idp-credentials/{credential_id}/retire`
- updateServiceProvider() : SamlServiceProvider
- `PUT /api/v1/tenants/{tenant_id}/saml/service-providers/{sp_id}` — a **replacement**: every member the body omits takes its default, it is not kept. `entity_id` is immutable.
Methods
__construct()
public
__construct(ManagementTransport $transport[, NamespaceScope $scope = new NamespaceScope() ][, string|null $clientOrgId = null ][, string|null $clientTenantId = null ]) : mixed
Parameters
- $transport : ManagementTransport
-
The one wire path (§27.8).
- $scope : NamespaceScope = new NamespaceScope()
-
Per-handle
{org_id}/{tenant_id}overrides. - $clientOrgId : string|null = null
-
The client's own organization id, or
null. - $clientTenantId : string|null = null
-
The client's own tenant id, or
null.
createServiceProvider()
`POST /api/v1/tenants/{tenant_id}/saml/service-providers`
public
createServiceProvider(SamlServiceProviderInput $body) : SamlServiceProvider
sp_signing_cert_pem must be RSA (2048 bits or more) or ECDSA on P-256, P-384 or P-521;
an ECDSA certificate verifies HTTP-POST requests only -- the HTTP-Redirect binding
is RSA-only (§29.3 rule 2). encrypt_assertions: true is refused while encryption is
unimplemented. entity_id is unique per tenant (409) and immutable once created.
Parameters
- $body : SamlServiceProviderInput
-
the request body
Return values
SamlServiceProviderdeleteServiceProvider()
`DELETE /api/v1/tenants/{tenant_id}/saml/service-providers/{sp_id}`
public
deleteServiceProvider(string $spId) : void
Returns nothing; the server answers with an empty body.
NOT idempotent (§27.4 rule 6): deleting something already deleted raises NotFoundError rather than succeeding quietly.
Ends no session: users already signed in to the SP stay signed in there until their SP session ends (§29.3 rule 5).
Parameters
- $spId : string
-
the
{sp_id}path parameter
forTenant()
A COPY of this handle scoped to `$tenantId` (§27.4 rule 3). See {@see self::inOrg()} for why it copies.
public
forTenant(string $tenantId) : static
Parameters
- $tenantId : string
Return values
staticgetIdp()
`GET /api/v1/tenants/{tenant_id}/saml/idp`
public
getIdp() : SamlIdpInfo
Return values
SamlIdpInfogetServiceProvider()
`GET /api/v1/tenants/{tenant_id}/saml/service-providers/{sp_id}`
public
getServiceProvider(string $spId) : SamlServiceProvider
Parameters
- $spId : string
-
the
{sp_id}path parameter
Return values
SamlServiceProviderinOrg()
A COPY of this handle scoped to `$orgId` (§27.4 rule 3).
public
inOrg(string $orgId) : static
Returns a new handle rather than mutating this one. An administrator holding a handle to their own organization should not find it repointed at someone else's because an unrelated code path re-scoped a shared object — and on a management surface that failure mode writes to the wrong tenant rather than merely reading from it.
Parameters
- $orgId : string
Return values
staticissueIdpCredential()
`POST /api/v1/tenants/{tenant_id}/saml/idp-credentials`
public
issueIdpCredential(IssueSamlIdpCredential $body) : SamlIdpCredential
Generates an RSA-4096 key on the server, which takes seconds; the key is never returned.
An occupied slot is 409 (§29.3 rule 7).
Parameters
- $body : IssueSamlIdpCredential
-
the request body
Return values
SamlIdpCredentiallistIdpCredentials()
`GET /api/v1/tenants/{tenant_id}/saml/idp-credentials`
public
listIdpCredentials() : array<int, SamlIdpCredential>
Returns the server's complete list. This endpoint is NOT paginated, so the result is a
plain list and never a Page (§27.4 rule 4).
Return values
array<int, SamlIdpCredential>listServiceProviders()
`GET /api/v1/tenants/{tenant_id}/saml/service-providers`
public
listServiceProviders([PageRequest|null $page = null ]) : Page<string|int, SamlServiceProvider>
Returns ONE page. Page::$total is the server's count across all pages and is not
count($page) — see §27.4 rule 4.
Parameters
- $page : PageRequest|null = null
-
which page to fetch; defaults to the first
Return values
Page<string|int, SamlServiceProvider>parseSpMetadata()
`POST /api/v1/tenants/{tenant_id}/saml/parse-sp-metadata`
public
parseSpMetadata(ParseSamlSpMetadata $body) : SamlSpMetadataDraft
Parses and stores nothing (§29.3 rule 6): the result is a draft to review and pass
to createServiceProvider(). Exactly one of metadata_xml and metadata_url must be
set -- use ParseSamlSpMetadata::fromUrl() or ::fromXml(); both or neither is refused
locally with a ValidationError, before any request. The
metadata's own signature is not evaluated. 503 in a server built without SAML.
Parameters
- $body : ParseSamlSpMetadata
-
the request body
Return values
SamlSpMetadataDraftpromoteIdpCredential()
`POST /api/v1/tenants/{tenant_id}/saml/idp-credentials/{credential_id}/promote`
public
promoteIdpCredential(string $credentialId) : SamlIdpCredentialPromotion
credential_id must be the tenant's current next credential; in one transaction the
old active is retired -- its key destroyed -- and next becomes active (§29.3 rule
7).
Parameters
- $credentialId : string
-
the
{credential_id}path parameter
Return values
SamlIdpCredentialPromotionretireIdpCredential()
`POST /api/v1/tenants/{tenant_id}/saml/idp-credentials/{credential_id}/retire`
public
retireIdpCredential(string $credentialId) : SamlIdpCredential
Retiring the active credential with no successor stops SAML sign-on for the whole
tenant at once (§29.3 rule 7) -- it is the incident response to a leaked key. The key
is destroyed. The safe rotation is: issue into next, wait until every SP has refreshed
the metadata, then promote.
Parameters
- $credentialId : string
-
the
{credential_id}path parameter
Return values
SamlIdpCredentialupdateServiceProvider()
`PUT /api/v1/tenants/{tenant_id}/saml/service-providers/{sp_id}` — a **replacement**: every member the body omits takes its default, it is not kept. `entity_id` is immutable.
public
updateServiceProvider(string $spId, SamlServiceProviderInput $body) : SamlServiceProvider
PUT /api/v1/tenants/{tenant_id}/saml/service-providers/{sp_id}.
An omitted member takes its default, not its stored value: enabled and
sign_responses default to true, name_id_format to persistent, the other flags to
false, certificates and slo_url / slo_binding to null, the lists to empty (§29.2).
Start from getServiceProvider() and ReadModifyWrite::samlServiceProvider(). entity_id is immutable:
changing it is 400 -- register a new service provider instead (§29.3 rule 3). An ECDSA
sp_signing_cert_pem verifies HTTP-POST requests only; HTTP-Redirect is RSA-only.
Parameters
- $spId : string
-
the
{sp_id}path parameter - $body : SamlServiceProviderInput
-
the request body