Identity administration
Manage the identity service from Python: its tenants, who belongs to each, the people, agents and Istari services that sign in (its principals), their keys and their roles. You can also request tokens from the identity service.
These methods are on the identity attribute of an IstariAdmin instance. They are grouped by subject: admin.identity.tenants, admin.identity.memberships, admin.identity.principals, admin.identity.keys, admin.identity.roles and admin.identity.oauth. Keyword-only parameters are marked (keyword).
The web app says suspend and reactivate where these methods say deactivate() and activate().
admin.identity needs istari-digital-client 13.2.0 or later. IstariAdmin is in beta: its methods may change between releases without a deprecation period.
Requirements
The identity service has two APIs, v1 and v2. admin.identity uses v2. Setup covers installing the SDK and creating a key. Set these on the Configuration:
- A key. Set
identity_service_secret_fileoridentity_service_secret. - A URL. Set
digital_api_url, the gateway. To reach the services directly instead, set bothidentity_urlandregistry_url. - The v2 API. Leave
identity_api_versionat its default,"auto", or set it to"v2".admin.identityis unavailable under"v1", and under"auto"when the identity service does not serve v2.
When any of these is missing, the first call on admin.identity raises ConfigurationError instead of calling a v2 method. A client configured with a key can still end up using a personal access token, and then raises the same error; Key or personal access token lists the settings that cause this. Under "auto", the check may first fetch a token to learn which API the identity service serves. If that fetch fails, it raises IdentityServiceError.
Most methods that change something also need a Platform Administrator or a Tenant Administrator (see Who may call). Only people can hold those roles, so run administration scripts with a person's key. A caller without the role is refused; see Errors.
from istari_digital_client import Configuration, IstariAdmin
admin = IstariAdmin(Configuration(
digital_api_url="https://your-instance.istari.digital",
identity_service_secret_file="/path/to/your/key.json",
))
# A tenant your IT administrator has already linked to your sign-in provider
tenant = admin.identity.tenants.get("your-tenant-id")
person = admin.identity.principals.humans.create(email="ada@example.com", tenant_id=tenant.id)
admin.identity.roles.grant_tenant_role(tenant.id, role="tenant_admin", principal_id=person.principal_id)
Get a tenant's id from tenants.list().
Tenant management
On an installation with tenant management, the registry reads people and roles from the identity service instead of your sign-in provider. Other pages of this SDK reference say where the registry then behaves differently. The glossary entry describes how to tell from the web app whether your installation has tenant management. For example, Platform Administrators on such an installation have a Platform Admin Console with a Tenants page.
On an installation without tenant management, the registry takes roles from your sign-in provider, so role grants made here do not change what people may do in the registry.
With tenant management, the registry authenticates callers through the identity service. Your IT administrator turns it on with the Helm values identity.enabled, which deploys the identity service, and identity.clientIntegration.enabled, which makes the registry and the web app authenticate through it. API Gateway lists the other settings these values need.
Who may call
Two roles let a caller administer identities. Only people can hold them; agents cannot.
| Role | Role id | Scope | Administers |
|---|---|---|---|
| Platform Administrator | admin | Platform | Every tenant, principal and grant on the installation |
| Tenant Administrator | tenant_admin | One tenant | That tenant, its members and the grants held in it |
Where a method is restricted, its description says who may call it.
When the caller is not a Platform Administrator, the identity service refuses these calls against a Platform Administrator with 403 target_is_platform_admin:
- deactivating or activating a Platform Administrator
- revoking a Platform Administrator's membership or role grants
Your IT administrator creates the installation's first Platform Administrator.
Errors
The SDK raises its usual exceptions, which you can import from istari_digital_client:
| Status | Exception |
|---|---|
| 400 | BadRequestError |
| 403 | PermissionDeniedError |
| 404 | NotFoundError |
| 409 | ConflictError |
Each method below lists its refusals by error code. A refusal is a 409 unless its entry names another status. To read the code, parse the exception's response, which holds the JSON body as a string: json.loads(e.response)["error"].
Two refusals depend on what the caller may see:
- A caller who may not see a tenant or principal gets
NotFoundError, as if it did not exist. - A caller who may see it but may not perform the operation gets
PermissionDeniedError. So does a caller whose own principal is deactivated.
Paging
Methods that return Page read their results one page at a time:
- Iterating a
Pagefetches every page in turn. .itemsholds the current page only.take(n)stops afternitems.
limit sets the page size. The server may use a smaller one.
Tenants
admin.identity.tenants
tenants.list()
List the tenants the caller may see. A Platform Administrator sees every tenant. Anyone else sees the tenants they administer or belong to.
- Return Type: List[Tenant]
tenants.get()
Read one tenant.
-
Parameters: tenant_id (str) – The tenant's id. (required)
-
Return Type: Tenant
tenants.create()
Create a tenant. Only a Platform Administrator may call it.
-
The slug cannot be changed later, because issued tokens carry it.
-
A new tenant is not ready for sign-in. Your IT administrator must first link it to an organization in your sign-in provider; Create a tenant in the Administrator Guide describes what to give them. Until then, pre-registering people in it is refused with
tenant_not_mapped. -
Parameters:
- slug (str) – Unique, permanent handle for the tenant: 1 to 63 lowercase letters, digits and single hyphens, starting and ending with a letter or digit. (required, keyword)
- display_name (str, optional) – Name shown to people. (keyword)
- description (str, optional) – Free-text description. (keyword)
-
Return Type: Tenant
-
Refusals:
tenant_exists– a tenant already has this slug.
tenants.update()
Change a tenant's display name or description. A Platform Administrator, or a Tenant Administrator of this tenant, may call it.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- display_name (str, optional) – New display name. (keyword)
- description (str, optional) – New description. (keyword)
-
Return Type: Tenant
tenants.deactivate()
Take a tenant out of service. Only a Platform Administrator may call it.
Every member of the tenant is deactivated. By default, every role grant held in the tenant is revoked too, and so are the members' memberships and other role grants. When a principal loses its membership lists what is revoked.
When this tenant was the default tenant, the oldest other active tenant becomes the default. default_reassigned_to names it.
-
Parameters: tenant_id (str) – The tenant's id. (required)
-
Return Type: TenantDeactivation
-
Refusals:
last_active_tenant– this is the only active tenant. Activate another tenant first.last_administrator– no active human Platform Administrator would remain.
tenants.activate()
Return a deactivated tenant to service. Only a Platform Administrator may call it.
Activating a tenant only returns it to service. It does not restore revoked memberships or grants, reactivate any principal, or make the tenant the default again.
-
Parameters: tenant_id (str) – The tenant's id. (required)
-
Return Type: Tenant
tenants.set_default()
Make this tenant the default tenant. The tenant that was the default loses the designation. Only a Platform Administrator may call it.
-
Parameters: tenant_id (str) – The tenant's id. (required)
-
Return Type: Tenant
-
Refusals:
inactive_tenant– the tenant is deactivated. Activate it first.
Memberships
admin.identity.memberships
A membership places a principal in a tenant. A principal can hold one granted membership at a time.
When a principal loses its membership
A person or agent left with no granted membership in an active tenant is deactivated. That happens when you revoke its membership, or deactivate its tenant.
What else is revoked depends on the call. "By default" means unless your IT administrator has turned this off; see the note below the table.
| Revoked | memberships.revoke() | tenants.deactivate() |
|---|---|---|
| Its membership in this tenant | Always | By default |
| Its role grants in this tenant | Always | By default |
Its other role grants, including platform roles such as admin | By default | By default |
Activating the principal or the tenant again restores none of these.
The identity service setting ISTARI_DIGITAL_IDENTITY_SERVICE_TENANT_DEACTIVATION_REVOCATION_CASCADE controls the "by default" revocations. It defaults to true. Set to false, it keeps them in place for both calls, despite its name. It is listed in the identity service's Configuration Reference.
Move a principal to another tenant
A principal can hold only one granted membership, so moving it takes these steps:
- Revoke its membership in the old tenant with
memberships.revoke(). This deactivates the principal and revokes its role grants, as the table above describes. - Grant it a membership in the new tenant with
memberships.grant(). - Reactivate it with
principals.activate(). - If it held roles, grant them again, with
roles.grant_tenant_role()orroles.grant_principal_role().
memberships.list()
Page through a tenant's members of every kind. Each record includes the member's principal. A caller who is a member of the tenant but does not administer it sees only its people.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- limit (int, optional) – Page size. (keyword)
-
Return Type: Page[Membership]
memberships.list_humans()
Page through a tenant's people.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- limit (int, optional) – Page size. (keyword)
-
Return Type: Page[Membership]
memberships.list_agents()
Page through a tenant's agents.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- limit (int, optional) – Page size. (keyword)
-
Return Type: Page[Membership]
memberships.list_for_principal()
List one principal's memberships, all in a single page.
-
Parameters: principal_id (str, optional) – The principal's id, or
"me"for the caller. Default:"me". -
Return Type: Page[Membership]
memberships.grant()
Grant a principal a membership in a tenant. A Platform Administrator, or a Tenant Administrator of the tenant, may call it, and the caller must be a person. If the principal already holds this membership, the existing record is returned.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- principal_id (str, optional) – The principal to add. (keyword)
- email (str, optional) – The email address of an existing person to add. (keyword)
Pass exactly one of
principal_idandemail. Passing neither or both raisesValueError. To add someone who has no principal yet, pre-register them withprincipals.humans.create(). -
Return Type: Membership
-
Refusals:
membership_limit– the principal already holds a granted membership in another tenant. See Move a principal to another tenant.tenant_deactivated– the tenant is deactivated.
memberships.revoke()
End a principal's membership in a tenant. A Platform Administrator, or a Tenant Administrator of the tenant, may call it, and the caller must be a person.
The method returns the membership record, now with status revoked. Revoking also deactivates the principal and revokes role grants; see When a principal loses its membership.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- principal_id (str) – The member's id. (required)
-
Return Type: Membership
-
Refusals:
self_revocation– the caller is revoking their own membership.- 403
target_is_platform_admin– the member is a Platform Administrator and the caller is not. last_administrator– no active human Platform Administrator would remain.
Principals
admin.identity.principals
A principal is anything that signs in to the identity service:
- a person (
human) - an agent (
agent) - one of Istari's own components (
platform_service)
Methods that can return any kind return a Principal wrapper.
principals.list()
Page through the principals of every kind that the caller may see.
A tenant member with no administrator role sees only their own tenant's people, and only by passing kind="human" or calling principals.humans.list(). Without that filter, their page is empty.
-
Parameters:
- tenant_id (str, optional) – Only principals in this tenant. (keyword)
- kind (str, optional) – One of
human,agent,platform_service. (keyword) - limit (int, optional) – Page size. (keyword)
-
Return Type: Page[Principal]
principals.get()
Read one principal of any kind.
-
Parameters: principal_id (str) – The principal's id. (required)
-
Return Type: Principal
principals.me()
Read the caller's own principal.
- Return Type: Principal
principals.resolve()
Read many principals in one request. Ids that do not exist, or that the caller may not see, are left out of the result rather than refused.
-
Parameters: ids (List[str]) – Principal ids. (required)
-
Return Type: PrincipalBatch
principals.deactivate()
Take a principal of any kind out of service. A Platform Administrator, or a Tenant Administrator of the principal's tenant, may call it.
Its memberships and role grants are kept, so activating it restores its access.
-
Parameters: principal_id (str) – The principal's id. (required)
-
Return Type: Principal
-
Refusals:
last_administrator– no active human Platform Administrator would remain.- 403
target_is_platform_admin– the principal is a Platform Administrator and the caller is not.
principals.activate()
Return a deactivated principal to service, with the grants it kept. A Platform Administrator, or a Tenant Administrator of the principal's tenant, may call it.
-
Parameters: principal_id (str) – The principal's id. (required)
-
Return Type: Principal
-
Refusals:
no_granted_membership– the principal holds no granted membership. Grant it one first withmemberships.grant().- 403
target_is_platform_admin– the principal is a Platform Administrator and the caller is not.
People
admin.identity.principals.humans
principals.humans.list()
Page through people.
-
Parameters:
- tenant_id (str, optional) – Only people in this tenant. (keyword)
- limit (int, optional) – Page size. (keyword)
- Filters, each keyword and optional, passed to the identity service unchanged:
- email (str)
- upstream_provider (str)
- upstream_user_id (str)
- email_verified (bool)
- pre_registered (bool) –
Truefor people who have never signed in. - active (bool)
- role (str) – Holders of this role id.
- role_scope (str) –
platformortenant. - created_before, created_after (str) – RFC 3339 timestamps.
-
Return Type: Page[Principal]
principals.humans.get()
Read one person. A principal of another kind is not found.
-
Parameters: principal_id (str) – The person's principal id. (required)
-
Return Type: Human
principals.humans.create()
Pre-register a person by email into a tenant, before their first sign-in. A Platform Administrator, or a Tenant Administrator of the tenant, may call it.
This call sends no invitation and creates no account in your sign-in provider. The person needs an account there that your IT administrator has set up. If that account's verified email address matches, the person's first sign-in with it claims the pre-registered record.
-
Parameters:
- email (str) – The person's email address. (required, keyword)
- tenant_id (str) – The tenant to place them in. A deactivated or unknown tenant raises
NotFoundError. (required, keyword) - display_name (str, optional) – Name shown to people. When omitted, it is the given and family names joined. (keyword)
- given_name (str, optional) – Given name. (keyword)
- family_name (str, optional) – Family name. (keyword)
-
Return Type: Human
-
Refusals:
email_taken– another person already has this email address.tenant_not_mapped– the tenant is not linked to an organization in your sign-in provider, so no sign-in could claim the record. Ask your IT administrator to link it.
principals.humans.update()
Change the email address of a person who has not signed in yet. A Platform Administrator, or a Tenant Administrator of the person's tenant, may call it.
-
Parameters:
- principal_id (str) – The person's principal id. (required)
- email (str) – The new email address. (required, keyword)
-
Return Type: Human
-
Refusals:
already_signed_in– the person has signed in, so the address can no longer change.email_taken– another person already has this email address.
principals.humans.deactivate()
Take a person out of service. This is the same operation as principals.deactivate().
-
Parameters: principal_id (str) – The person's principal id. (required)
-
Return Type: Human
Agents
admin.identity.principals.agents
An agent has two ids. Reading, updating and deactivating it take its principal_id. Its client_id is the name it signs in as, and goes into its key file.
For an agent that runs in your own tenant, such as a build server, use the registry's create_agent_with_key() instead. It creates the agent's principal and the registry's user record for it in one step. principals.agents.create() creates only the principal, and the registry adds the user record when the agent first signs in. Use it to place an agent in another tenant.
principals.agents.list()
Page through agents.
-
Parameters:
- tenant_id (str, optional) – Only agents in this tenant. (keyword)
- limit (int, optional) – Page size. (keyword)
- Filters, each keyword and optional, passed to the identity service unchanged:
- client_id (str)
- username (str)
- created_by (str) – The creator's principal id.
- active (bool)
- role (str) – Holders of this role id.
- role_scope (str) –
platformortenant. - created_before, created_after (str) – RFC 3339 timestamps.
-
Return Type: Page[Principal]
principals.agents.get()
Read one agent. A principal of another kind is not found.
-
Parameters: principal_id (str) – The agent's principal id. (required)
-
Return Type: Agent
principals.agents.create()
Create an agent and register its first key. A Platform Administrator, or a Tenant Administrator of the tenant, may call it. The person who calls it is recorded as the agent's creator.
-
Parameters:
- client_id (str) – The client id the agent authenticates as. (required, keyword)
- key (dict or CreateAgentKeyRequest) – The first key:
key_id(required), exactly one ofpublic_key_pemorpublic_key_jwk, and optionallynameandexpires_at. (required, keyword) - tenant_id (str, optional) – The tenant to place the agent in. (keyword)
- display_name (str, optional) – Name shown to people. (keyword)
The SDK also accepts
usernameandcreated_by. Leave both unset: the identity service refuses a request from your script that sets either, with 400invalid_request. -
Return Type: CreatedAgent
-
Refusals:
agent_exists– an agent already has this client id.
generate_client_keypair() makes the key pair, and write_credentials_json() saves the key file the agent signs in with.
from istari_digital_client import generate_client_keypair
# An agent placed in another tenant
credentials = generate_client_keypair(client_id="partner-sync")
agent = admin.identity.principals.agents.create(
client_id=credentials.client_id,
key={"key_id": credentials.key_id, "public_key_pem": credentials.public_key_pem},
tenant_id=other_tenant.id,
)
credentials.write_credentials_json("partner-sync-key.json")
principals.agents.update()
Change an agent's display name, the only field that can be edited. A Platform Administrator, or a Tenant Administrator of the agent's tenant, may call it.
-
Parameters:
- principal_id (str) – The agent's principal id. (required)
- display_name (str) – The new display name. (required, keyword)
The SDK also accepts
username. Leave it unset: the identity service refuses a request that sets it, with 400invalid_request. -
Return Type: Agent
principals.agents.deactivate()
Take an agent out of service. This is the same operation as principals.deactivate().
-
Parameters: principal_id (str) – The agent's principal id. (required)
-
Return Type: Agent
Keys
admin.identity.keys
Who may manage keys:
- A person may manage their own keys.
- A Platform Administrator, or a Tenant Administrator of the principal's tenant, may manage another principal's keys.
- While an agent is in its creator's tenant, the creator may list, read and revoke the agent's keys.
- An agent calling any key method gets
PermissionDeniedError.
keys.list()
List a principal's registered keys.
-
Parameters: principal_id (str, optional) – The principal's id, or
"me"for the caller. Default:"me". -
Return Type: PrincipalKeys
keys.get()
Read one key's metadata.
-
Parameters:
- principal_id (str) – The principal's id. (required)
- key_id (str) – The key's id. (required)
-
Return Type: KeyMeta
keys.register()
Register the public half of a key pair you already hold. Only the public key is sent.
-
Parameters:
- principal_id (str) – The principal's id. (required)
- credentials (GeneratedClientCredentials) – The key pair, for example from
generate_client_keypair(). (required) - name (str, optional) – A label for the key. (keyword)
- expires_at (str, optional) – When the key expires, as an RFC 3339 timestamp. (keyword)
-
Return Type: KeyMeta
-
Refusals:
not_signed_in– the person has not signed in for the first time yet.duplicate_key_id– the principal already has a key with this id.
keys.generate_and_register()
Generate a key pair, register its public half, and return both the credentials and the key's metadata. Save the credentials: the private key exists only in the returned object.
-
Parameters:
- principal_id (str) – The principal's id, or
"me". (required) - client_id (str, optional) – The client id written into the credentials. Defaults to
principal_id. For an agent, pass the agent'sclient_id, as the example below does. Required whenprincipal_idis"me";keys.list("me").client_idgives the caller's. (keyword) - key_id (str, optional) – Defaults to a random id. (keyword)
- name (str, optional) – A label for the key. (keyword)
- principal_id (str) – The principal's id, or
-
Return Type: tuple[GeneratedClientCredentials, KeyMeta]
-
Refusals: as for
keys.register().
agent = admin.identity.principals.agents.get("agent-principal-id")
credentials, key = admin.identity.keys.generate_and_register(
agent.principal_id, client_id=agent.client_id, name="build-server"
)
credentials.write_credentials_json("agent-key.json")
keys.revoke()
Revoke a key.
-
Parameters:
- principal_id (str) – The principal's id. (required)
- key_id (str) – The key's id. (required, keyword)
-
Return Type: None
Roles
admin.identity.roles
Who may grant and revoke roles:
- Only a person may grant or revoke a role.
- A platform-scoped role, such as
admin: only a Platform Administrator. - A tenant-scoped role, such as
tenant_admin: a Platform Administrator, or a Tenant Administrator of that tenant. - No caller may revoke their own
adminortenant_admingrant.
The role parameters below take a role id. roles.list() returns the full catalog.
roles.list()
List the role catalog, all in a single page. Every authenticated, active caller may read it.
- Return Type: Page[Role]
roles.holders()
Page through the principals holding a role.
-
Parameters:
- role (str) – The role id. (required)
- tenant_id (str, optional) – Only grants held in this tenant. This names the tenant the role is held in, not the holder's own tenant. (keyword)
- limit (int, optional) – Page size. (keyword)
-
Return Type: Page[Principal]
roles.list_tenant_roles()
Page through the role grants held in a tenant. A member of the tenant who does not administer it may not list them.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- limit (int, optional) – Page size. (keyword)
-
Return Type: Page[RoleAssignment]
roles.grant_tenant_role()
Grant a tenant-scoped role in a tenant. If the principal already holds the role there, the existing grant is returned. For a platform-scoped role, use roles.grant_principal_role().
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- role (str) – The role id, for example
tenant_admin. (required, keyword) - principal_id (str) – The principal receiving the role. (required, keyword)
-
Return Type: RoleAssignment
-
Refusals:
inactive_tenant– the tenant is deactivated.principal_deactivated– the principal is deactivated. Activate it first.
roles.revoke_tenant_role()
Revoke a tenant-scoped grant.
-
Parameters:
- tenant_id (str) – The tenant's id. (required)
- role (str) – The role id. (required, keyword)
- principal_id (str) – The holder's id. (required, keyword)
-
Return Type: None
-
Refusals:
- 400
scope_mismatch– the role is platform-scoped. Useroles.revoke_principal_role(). self_role_revocation– the caller is revoking their owntenant_admingrant.- 403
target_is_platform_admin– the holder is a Platform Administrator and the caller is not.
- 400
roles.list_principal_roles()
List one principal's role grants, all in a single page. This method does not accept "me"; pass principals.me().actual_instance.principal_id (see principals.me()).
-
Parameters: principal_id (str) – The principal's id. (required)
-
Return Type: Page[RoleAssignment]
roles.grant_principal_role()
Grant a role to a principal: a platform-scoped role such as admin, or a tenant-scoped role in one tenant. If the principal already holds the role, the existing grant is returned.
-
Parameters:
- principal_id (str) – The principal's id. (required)
- role (str) – The role id. (required, keyword)
- tenant_id (str, optional) – The tenant a tenant-scoped role applies in. Omit it for a platform-scoped role. (keyword)
-
Return Type: RoleAssignment
-
Refusals:
inactive_tenant– the tenant is deactivated.principal_deactivated– the principal is deactivated. Activate it first.
roles.revoke_principal_role()
Revoke one of a principal's grants. The grant is marked revoked, not deleted.
-
Parameters:
- principal_id (str) – The principal's id. (required)
- role (str) – The role id. (required, keyword)
- tenant_id (str, optional) – The tenant of a tenant-scoped grant. Omit it for a platform-scoped grant. (keyword)
-
Return Type: None
-
Refusals:
last_administrator– no active human Platform Administrator would remain.self_role_revocation– the caller is revoking their ownadminortenant_admingrant.- 403
target_is_platform_admin– the principal is a Platform Administrator and the caller is not.
OAuth
admin.identity.oauth
oauth.issue_token()
Request a v2 token from the identity service. The client fetches and refreshes its own tokens, so most scripts never call this.
Each grant type does one job:
-
client_credentialsauthenticates a principal with a client assertion signed by its registered key. -
authorization_codecompletes a browser sign-in. The SDK has no method for the redirect that starts one. -
refresh_tokenrenews a token. -
Parameters:
- grant_type (str) – One of the grant types above. Default:
client_credentials. (keyword) - client_assertion (str, optional) – For
client_credentials: a JWT signed with the principal's registered key. Its issuer and subject are the client id, and its audience is the token endpoint. (keyword) - client_assertion_type (str) – Default:
urn:ietf:params:oauth:client-assertion-type:jwt-bearer. (keyword) - code (str, optional) – For
authorization_code: the code from the callback redirect. (keyword) - redirect_uri (str, optional) – For
authorization_code: the same redirect URI the sign-in started with. (keyword) - refresh_token (str, optional) – For
refresh_token. (keyword)
- grant_type (str) – One of the grant types above. Default:
-
Return Type: Token
oauth.introspect()
Report whether a token is active, and whom it was issued to. Only Istari's own platform services may call it; a script's call is refused. An invalid token returns active=False rather than an error.
-
Parameters:
- token (str) – The token to introspect. (required)
- client_assertion (str) – The platform service's client assertion. Its audience is the identity service base URL, not the introspection endpoint. (required, keyword)
- client_assertion_type (str) – Default:
urn:ietf:params:oauth:client-assertion-type:jwt-bearer. (keyword)
-
Return Type: Introspection
Deprecated v1 key methods
The SDK's key methods written for the identity service's v1 API are deprecated, like the v1 key routes themselves. They still work whatever identity_api_version the Configuration sets, and are scheduled for removal with no date set.
| Deprecated | Replacement |
|---|---|
admin.keys.register(), register_key() | admin.identity.keys.register() |
admin.keys.generate_and_register(), generate_keypair_and_register() | admin.identity.keys.generate_and_register() |
admin.keys.list(), list_keys() | admin.identity.keys.list() |
admin.keys.get(), get_key() | admin.identity.keys.get() |
admin.keys.revoke(), revoke_key() | admin.identity.keys.revoke() |
exchange_pat(), generate_keypair_and_exchange() | None: v2 has no personal access token exchange. Download a key from the web app; see Setup. |
admin.keys.generate_keypair() sends no request and is not deprecated.
The deprecated methods appear in up to three places, which share the routing and warnings below:
admin.keysonIstariAdmin, named in the table's first column.client.keysonClientandV3Client. Keys documents its methods and parameters.- The functions in
istari_digital_client.identity.v1, such asregister_key()andexchange_pat().
How the deprecated methods route
You do not need to set identity_api_version, or the methods' own api_version argument, to use these methods. In this section, "auto", "v1" and "v2" are values of the api_version argument. It takes "auto" (the default, which None also means), "v1" or "v2", as a string or an IdentityApiVersion member. Any other value raises ConfigurationError.
PAT exchange authenticates with the personal access token itself, and ignores identity_api_version and its environment variable, ISTARI_IDENTITY_API_VERSION. It uses the v1 route under "auto" and "v1". Under "v2" it raises ConfigurationError before any request.
Key management under "auto" uses the API that its identity service client resolves to. For client.keys, that client is built from the Configuration. For admin.keys and the istari_digital_client.identity.v1 functions, it is the identity service client you pass as their ir_client argument.
-
On v1, the call uses the v1 routes.
-
On v2, the call first looks up the principal id, unless it is
"me", so that ids that worked against v1 keep working. It looks for an agent with thatclient_id, or a person with thatupstream_user_id. The result picks the route:Principal id Route "me"v2 key routes An id the lookup resolves to one principal v2 key routes A hyphenated UUID that matches no principal v2 key routes, taking it as the principal id Any other id that matches no principal v1 routes, with the id unchanged An id that matches several principals v1 routes, with the id unchanged An id whose lookup is refused with 403 v1 routes, with the id unchanged An id that matches a person's upstream_user_idbut not their client idv1 routes, with the id unchanged An id whose lookup fails any other way KeyRegistrationError, not retried on v1Any id, when a v2 key route answers 404 KeyRegistrationError, not retried on v1 -
Calls v2 cannot express go to v1: a register call with
usernameordisplay_name, and"me"withkind=AGENT.kindis the deprecated methods' principal-kind argument.client.keysrejects the second case withValueError.
Results have the v1 types, whichever route serves the call.
The explicit values override this:
"v1"always uses the v1 routes."v2"never falls back to v1:- A call v2 cannot express raises
ConfigurationErrorbefore any request. - An id that is not a UUID and matches no principal the caller may see raises
KeyRegistrationErrorwith codeprincipal_not_found. So does an id that matches a person'supstream_user_idbut not their client id. - An id that matches several principals raises
KeyRegistrationErrorwith codeprincipal_ambiguous.
- A call v2 cannot express raises
Two warnings tell you that a call used v1:
DeprecationWarning: the first time each method reaches a v1 route in a process. It names the method's replacement, if it has one.- A
loggingwarning: under"auto"with v2 in force, on every call that v2 cannot express.
An unknown kind raises an error before any request:
- the key-management methods raise
KeyRegistrationError - PAT exchange raises
ExchangePatError, orConfigurationErrorunder"v2"
To handle a ConfigurationError from client.keys or the istari_digital_client.identity.v1 functions, catch ValueError. They raise the ConfigurationError defined in istari_digital_client.legacy.configuration, which except istari_digital_client.ConfigurationError does not catch. Both classes subclass ValueError.
Data types
The types below are in istari_digital_client.identity.v2.models. Timestamps are RFC 3339 strings unless the type is datetime.
Tenant
Returned by the tenant methods.
| Attribute | Type | Description |
|---|---|---|
id | str | Tenant id |
slug | str | Permanent handle |
display_name | str | Name shown to people |
description | str | Free-text description |
active | bool | Whether the tenant is in service |
is_default | bool | Whether this is the default tenant |
member_count | int | People with a granted membership; agents are not counted |
created_at | datetime | When the tenant was created |
updated_at | datetime | When the tenant was last changed |
TenantDeactivation
Returned by tenants.deactivate(). Every Tenant attribute, plus:
| Attribute | Type | Description |
|---|---|---|
default_reassigned_to | str or None | The tenant that became the default, when this tenant was the default before |
Membership
Returned by the membership methods.
| Attribute | Type | Description |
|---|---|---|
tenant_id | str | The tenant |
principal_id | str | The member |
principal | Principal | The member's principal record |
status | str | granted or revoked |
granted_at | str | When the membership was granted |
revoked_at | str or None | When it was revoked; None if granted |
Principal
A wrapper over one Human, Agent or PlatformService. The wrapper has no record fields of its own: read them from actual_instance, for example principal.actual_instance.kind.
Every kind of record, read through actual_instance, has these attributes:
| Attribute | Type | Description |
|---|---|---|
principal_id | str | Principal id |
kind | str | human, agent or platform_service |
active | bool | Whether the principal is in service |
tenancy | List[TenancyEntry] or None | The tenant the principal belongs to, if any |
role_assignments | List[RoleAssignment] or None | The principal's role grants |
created_at | str | When the principal was created |
updated_at | str | When the principal was last changed |
Human
A person. Every attribute common to Principal records, plus:
| Attribute | Type | Description |
|---|---|---|
email | str | Email address |
email_verified | bool | Whether the sign-in provider has verified the address |
display_name | str | Name shown to people |
upstream_provider | str | The sign-in provider |
upstream_tenant_id | str | The id of the person's organization at the sign-in provider |
upstream_user_id | str | The person's id at the sign-in provider; empty until they sign in |
last_login_at | datetime or None | Last sign-in; None until the first |
Agent
An agent. Every attribute common to Principal records, plus:
| Attribute | Type | Description |
|---|---|---|
client_id | str | The client id the agent authenticates as |
username | str | Username |
display_name | str | Name shown to people |
created_by | str or None | The creator's principal id; None if not recorded |
CreatedAgent
Returned by principals.agents.create(). Every Agent attribute, plus:
| Attribute | Type | Description |
|---|---|---|
key | KeyMeta | The key registered for the agent |
PlatformService
One of Istari's own components, such as the registry. Every attribute common to Principal records, plus client_id, client_type, component and redirect_uris.
TenancyEntry
| Attribute | Type | Description |
|---|---|---|
tenant_id | str | The tenant's id |
tenant_slug | str | The tenant's slug |
PrincipalBatch
Returned by principals.resolve().
| Attribute | Type | Description |
|---|---|---|
items | List[Principal] | The principals found and visible to the caller |
Role
Returned by roles.list().
| Attribute | Type | Description |
|---|---|---|
id | str | Role id, such as admin or tenant_admin |
display_name | str | Name shown to people |
description | str | What the role allows |
scope | str | platform or tenant |
holder_kinds | List[str] | The principal kinds that may hold the role |
RoleAssignment
One role grant.
| Attribute | Type | Description |
|---|---|---|
principal_id | str | The holder |
role_id | str | The role |
scope | str | platform or tenant |
tenant_id | str or None | The tenant of a tenant-scoped grant |
source | str | native if granted in the identity service, imported if brought in from the sign-in provider |
granted_at | str | When the role was granted |
KeyMeta
A registered key's metadata. The identity service never returns key material.
| Attribute | Type | Description |
|---|---|---|
key_id | str | Key id |
name | str | Label |
algorithm | str | Signing algorithm |
created_at | str | When the key was registered |
expires_at | str | When the key expires |
PrincipalKeys
Returned by keys.list().
| Attribute | Type | Description |
|---|---|---|
principal_id | str | The principal |
client_id | str | The principal's client id |
tenant_id | str | The principal's tenant |
active | bool | Whether the principal is active |
keys | List[KeyMeta] | The registered keys |
GeneratedClientCredentials
A generated key pair, from istari_digital_client.GeneratedClientCredentials. The private key is left out of repr() and string output.
| Attribute | Type | Description |
|---|---|---|
client_id | str | The client id the key signs as |
key_id | str | Key id |
public_key_pem | str | Public key, PEM-encoded |
private_key_pem | str | Private key, PEM-encoded |
write_credentials_json(path) writes the credentials as a key file that identity_service_secret_file accepts.
Token
Returned by oauth.issue_token().
| Attribute | Type | Description |
|---|---|---|
access_token | str | The identity service JWT |
token_type | str | Token type |
expires_in | int | Seconds until access_token expires |
refresh_token | str or None | Present when a session backs the sign-in |
id_token | str or None | The same JWT as access_token; browser sign-ins only |
Introspection
Returned by oauth.introspect().
| Attribute | Type | Description |
|---|---|---|
active | bool | Whether the token is valid |
principal_id | str or None | The token's principal |
principal_kind | str or None | The principal's kind |
client_id | str or None | The OAuth client the token was issued to |
tenant_id | str or None | The acting tenant; absent on a platform-service token |
tenant_slug | str or None | The acting tenant's slug |
tenant_roles | List[str] or None | Roles held in the acting tenant |
platform_roles | List[str] or None | Platform-scoped roles |