type UserNumber = nat64; type AccountNumber = nat64; type PublicKey = blob; type CredentialId = blob; type Aaguid = blob; type DeviceKey = PublicKey; type UserKey = PublicKey; type SessionKey = PublicKey; type FrontendHostname = text; type Timestamp = nat64; type HeaderField = record { text; text; }; type HttpRequest = record { method : text; url : text; headers : vec HeaderField; body : blob; certificate_version : opt nat16; }; type HttpResponse = record { status_code : nat16; headers : vec HeaderField; body : blob; upgrade : opt bool; }; type StreamingCallbackHttpResponse = record { body : blob; token : opt Token; }; type Token = record {}; type StreamingStrategy = variant { Callback : record { callback : func(Token) -> (StreamingCallbackHttpResponse) query; token : Token; }; }; type Purpose = variant { recovery; authentication; }; type KeyType = variant { unknown; platform; cross_platform; seed_phrase; browser_storage_key; }; // This describes whether a device is "protected" or not. // When protected, a device can only be updated or removed if the // user is authenticated with that very device. type DeviceProtection = variant { protected; unprotected; }; type Challenge = record { png_base64 : text; challenge_key : ChallengeKey; }; type DeviceData = record { pubkey : DeviceKey; alias : text; credential_id : opt CredentialId; aaguid : opt Aaguid; purpose : Purpose; key_type : KeyType; protection : DeviceProtection; origin : opt text; // Metadata map for additional device information. // // Note: some fields above will be moved to the metadata map in the future. // All field names of `DeviceData` (such as 'alias', 'origin, etc.) are // reserved and cannot be written. // In addition, the keys "usage" and "authenticator_attachment" are reserved as well. metadata : opt MetadataMap; }; // The same as `DeviceData` but with the `last_usage` field. // This field cannot be written, hence the separate type. type DeviceWithUsage = record { pubkey : DeviceKey; alias : text; credential_id : opt CredentialId; aaguid : opt Aaguid; purpose : Purpose; key_type : KeyType; protection : DeviceProtection; origin : opt text; last_usage : opt Timestamp; metadata : opt MetadataMap; }; type DeviceKeyWithAnchor = record { pubkey : DeviceKey; anchor_number : UserNumber; }; // Map with some variants for the value type. // Note, due to the Candid mapping this must be a tuple type thus we cannot name the fields `key` and `value`. type MetadataMap = vec record { text; variant { map : MetadataMap; string : text; bytes : vec nat8 }; }; type RegisterResponse = variant { // A new user was successfully registered. registered : record { user_number : UserNumber; }; // No more registrations are possible in this instance of the II service canister. canister_full; // The challenge was not successful. bad_challenge; }; type AddTentativeDeviceResponse = variant { // The device was tentatively added. added_tentatively : record { verification_code : text; // Expiration date, in nanos since the epoch device_registration_timeout : Timestamp; }; // Device registration mode is off, either due to timeout or because it was never enabled. device_registration_mode_off; // There is another device already added tentatively another_device_tentatively_added; // Passkey with this public key is already used passkey_with_this_public_key_is_already_used; }; type VerifyTentativeDeviceResponse = variant { // The device was successfully verified. verified; // Wrong verification code entered. Retry with correct code. wrong_code : record { retries_left : nat8; }; // Device registration mode is off, either due to timeout or because it was never enabled. device_registration_mode_off; // There is no tentative device to be verified. no_device_to_verify; }; type Delegation = record { pubkey : PublicKey; expiration : Timestamp; targets : opt vec principal; }; type SignedDelegation = record { delegation : Delegation; signature : blob; }; type GetDelegationResponse = variant { // The signed delegation was successfully retrieved. signed_delegation : SignedDelegation; // The signature is not ready. Maybe retry by calling `prepare_delegation` no_such_delegation; }; type InternetIdentityStats = record { users_registered : nat64; storage_layout_version : nat8; assigned_user_number_range : record { nat64; nat64; }; archive_info : ArchiveInfo; canister_creation_cycles_cost : nat64; // Map from event aggregation to a sorted list of top 100 sub-keys to their weights. // Example: {"prepare_delegation_count 24h ic0.app": [{"https://dapp.com", 100}, {"https://dapp2.com", 50}]} event_aggregations : vec record { text; vec record { text; nat64 } }; }; // Configuration parameters related to the archive. type ArchiveConfig = record { // The allowed module hash of the archive canister. // Changing this parameter does _not_ deploy the archive, but enable archive deployments with the // corresponding wasm module. module_hash : blob; // Buffered archive entries limit. If reached, II will stop accepting new anchor operations // until the buffered operations are acknowledged by the archive. entries_buffer_limit : nat64; // The maximum number of entries to be transferred to the archive per call. entries_fetch_limit : nat16; // Polling interval to fetch new entries from II (in nanoseconds). // Changes to this parameter will only take effect after an archive deployment. polling_interval_ns : nat64; }; // Information about the archive. type ArchiveInfo = record { // Canister id of the archive or empty if no archive has been deployed yet. archive_canister : opt principal; // Configuration parameters related to the II archive. archive_config : opt ArchiveConfig; }; // Rate limit configuration. // Currently only used for `register`. type RateLimitConfig = record { // Time it takes (in ns) for a rate limiting token to be replenished. time_per_token_ns : nat64; // How many tokens are at most generated (to accommodate peaks). max_tokens : nat64; }; // Captcha configuration // Default: // - max_unsolved_captchas: 500 // - captcha_trigger: Static, CaptchaEnabled type CaptchaConfig = record { // Maximum number of unsolved captchas. max_unsolved_captchas : nat64; // Configuration for when captcha protection should kick in. captcha_trigger : variant { // Based on the rate of registrations compared to some reference time frame and allowing some leeway. Dynamic : record { // Percentage of increased registration rate observed in the current rate sampling interval (compared to // reference rate) at which II will enable captcha for new registrations. threshold_pct : nat16; // Length of the interval in seconds used to sample the current rate of registrations. current_rate_sampling_interval_s : nat64; // Length of the interval in seconds used to sample the reference rate of registrations. reference_rate_sampling_interval_s : nat64; }; // Statically enable / disable captcha Static : variant { CaptchaEnabled; CaptchaDisabled; }; }; }; // Init arguments of II which can be supplied on install and upgrade. // // Each field is wrapped is `opt` to indicate whether the field should // keep the previous value or update to a new value (e.g. `null` keeps the previous value). // // Some fields, like `analytics_config`, have an additional nested `opt`, this indicates // enable/disable status (e.g. `opt null` disables a feature while `null` leaves it untouched). type InternetIdentityInit = record { // Set lowest and highest anchor assigned_user_number_range : opt record { nat64; nat64; }; // Configuration parameters related to the II archive. // Note: some parameters changes (like the polling interval) will only take effect after an archive deployment. // See ArchiveConfig for details. archive_config : opt ArchiveConfig; // Set the amounts of cycles sent with the create canister message. // This is configurable because in the staging environment cycles are required. // The canister creation cost on mainnet is currently 100'000'000'000 cycles. If this value is higher thant the // canister creation cost, the newly created canister will keep extra cycles. canister_creation_cycles_cost : opt nat64; // Rate limit for the `register` call. register_rate_limit : opt RateLimitConfig; // Configuration of the captcha in the registration flow. captcha_config : opt CaptchaConfig; // Configuration for Related Origins Requests. // If present, list of origins from where registration is allowed. related_origins : opt vec text; // Configuration for New Origin Flows. // If present, list of origins using the new authentication flow. new_flow_origins : opt vec text; // Configurations for OpenID clients openid_configs : opt vec OpenIdConfig; // Allowlist of domains that may be registered as discoverable SSO // providers via `add_discoverable_oidc_config`. When set, fully replaces // the built-in defaults. When unset, falls back to `dfinity.org` // (production) or `beta.dfinity.org` (everything else), keyed off // `is_production`. sso_discoverable_domains : opt vec text; // Configuration for Web Analytics analytics_config : opt opt AnalyticsConfig; // Configuration to show dapps explorer or not enable_dapps_explorer : opt bool; // Configuration to set the canister as production mode. // For now, this is used only to show or hide the banner. is_production : opt bool; // Configuration for dummy authentication used in e2e tests. dummy_auth : opt opt DummyAuthConfig; // Backend canister ID, needed for backward compatibility. backend_canister_id : opt principal; // Backend origin, needed to sync configuration with frontend. backend_origin : opt text; }; type ChallengeKey = text; type ChallengeResult = record { key : ChallengeKey; chars : text; }; type CaptchaResult = ChallengeResult; // Extra information about registration status for new devices type DeviceRegistrationInfo = record { // If present, the user has registered a new authentication method. This new authentication // method needs to be confirmed before 'expiration' in order to be added to the identity. tentative_device : opt DeviceData; // If present, the user has registered a new session. This new session needs to be confirmed before // 'expiration' in order for it be authorized to register an authentication method to the identity. tentative_session : opt principal; // The timestamp at which the anchor will turn off registration mode // (and the tentative device will be forgotten, if any, and if not verified) expiration : Timestamp; }; // Information about the anchor type IdentityAnchorInfo = record { // All devices that can authenticate to this anchor devices : vec DeviceWithUsage; // Device registration status used when adding devices, see DeviceRegistrationInfo device_registration : opt DeviceRegistrationInfo; // OpenID accounts linked to this anchor openid_credentials : opt vec OpenIdCredential; // The name of the Internet Identity name : opt text; // The timestamp at which the anchor was created created_at : opt Timestamp; }; type AnchorCredentials = record { credentials : vec WebAuthnCredential; recovery_credentials : vec WebAuthnCredential; recovery_phrases : vec PublicKey; }; type WebAuthnCredential = record { credential_id : CredentialId; pubkey : PublicKey; }; type DeployArchiveResult = variant { // The archive was deployed successfully and the supplied wasm module has been installed. The principal of the archive // canister is returned. success : principal; // Initial archive creation is already in progress. creation_in_progress; // Archive deployment failed. An error description is returned. failed : text; }; type BufferedArchiveEntry = record { anchor_number : UserNumber; timestamp : Timestamp; sequence_number : nat64; entry : blob; }; // OpenID specific types type Iss = text; type Sub = text; type Aud = text; type JWT = text; type Salt = blob; type OpenIdEmailVerification = variant { Unknown; Google; Microsoft; }; type OpenIdConfig = record { name : text; logo : text; issuer : text; client_id : text; jwks_uri : text; auth_uri : text; auth_scope : vec text; fedcm_uri : opt text; email_verification : opt OpenIdEmailVerification; }; // SSO provider config that uses two-hop discovery. // The backend fetches https://{discovery_domain}/.well-known/ii-openid-configuration // for { client_id, openid_configuration } and then fetches the standard OIDC // discovery at openid_configuration for { issuer, jwks_uri }. type DiscoverableOidcConfig = record { discovery_domain : text; }; // Resolved SSO provider state. // All fields other than discovery_domain are None until discovery completes. type OidcConfig = record { discovery_domain : text; client_id : opt text; openid_configuration : opt text; issuer : opt text; }; type OpenIdCredentialKey = record { Iss; Sub; Aud }; type AnalyticsConfig = variant { Plausible : record { domain : opt text; hash_mode : opt bool; track_localhost : opt bool; api_host : opt text; }; }; type OpenIdCredential = record { iss : Iss; sub : Sub; aud : Aud; last_usage_timestamp : opt Timestamp; metadata : MetadataMapV2; // SSO discovery domain, looked up by `(iss, aud)` against the // canister's registered discoverable OIDC configs. `None` for // direct-provider credentials (Google / Apple / Microsoft) and for // SSO credentials whose provider is no longer registered. sso_domain : opt text; // Human-readable SSO name from the domain's // `/.well-known/ii-openid-configuration`. `None` when the domain // doesn't publish one — callers should fall back to `sso_domain` // for the label. sso_name : opt text; }; type OpenIdCredentialAddError = variant { Unauthorized : principal; JwtVerificationFailed; OpenIdCredentialAlreadyRegistered; InternalCanisterError : text; JwtExpired; }; type OpenIdCredentialRemoveError = variant { Unauthorized : principal; OpenIdCredentialNotFound; InternalCanisterError : text; }; type OpenIdDelegationError = variant { NoSuchAnchor; JwtVerificationFailed; NoSuchDelegation; JwtExpired; }; type OpenIdPrepareDelegationResponse = record { user_key : UserKey; expiration : Timestamp; anchor_number : UserNumber; }; // API V2 specific types // WARNING: These type are experimental and may change in the future. type IdentityNumber = nat64; // Map with some variants for the value type. // Note, due to the Candid mapping this must be a tuple type thus we cannot name the fields `key` and `value`. type MetadataMapV2 = vec record { text; variant { Map : MetadataMapV2; String : text; Bytes : vec nat8 }; }; // Authentication method using WebAuthn signatures // See https://www.w3.org/TR/webauthn-2/ // This is a separate type because WebAuthn requires to also store // the credential id (in addition to the public key). type WebAuthn = record { credential_id : CredentialId; pubkey : PublicKey; // Authenticator Attestation Global Unique Identifier (AAGUID) aaguid : opt Aaguid; }; // Authentication method using generic signatures // See https://internetcomputer.org/docs/current/references/ic-interface-spec/#signatures for // supported signature schemes. type PublicKeyAuthn = record { pubkey : PublicKey; }; // The authentication methods currently supported by II. type AuthnMethod = variant { WebAuthn : WebAuthn; PubKey : PublicKeyAuthn; }; // This describes whether an authentication method is "protected" or not. // When protected, a authentication method can only be updated or removed if the // user is authenticated with that very authentication method. type AuthnMethodProtection = variant { Protected; Unprotected; }; type AuthnMethodPurpose = variant { Recovery; Authentication; }; type AuthnMethodSecuritySettings = record { protection : AuthnMethodProtection; purpose : AuthnMethodPurpose; }; type AuthnMethodData = record { authn_method : AuthnMethod; security_settings : AuthnMethodSecuritySettings; // contains the following fields of the DeviceWithUsage type: // - alias // - origin // - authenticator_attachment: data taken from key_type and reduced to "platform", "cross_platform" or absent on migration // - usage: data taken from key_type and reduced to "recovery_phrase", "browser_storage_key" or absent on migration // Note: for compatibility reasons with the v1 API, the entries above (if present) // must be of the `String` variant. This restriction may be lifted in the future. metadata : MetadataMapV2; last_authentication : opt Timestamp; }; type OpenIDRegFinishArg = record { jwt : JWT; salt : Salt; name : text; }; // Extra information about registration status for new authentication methods type AuthnMethodRegistrationInfo = record { // If present, the user has registered a new authentication method. This new authentication // method needs to be confirmed before 'expiration' in order to be added to the identity. authn_method : opt AuthnMethodData; // If present, the user has registered a new session. This new session needs to be confirmed before // 'expiration' in order for it be authorized to register an authentication method to the identity. session : opt principal; // The timestamp at which the identity will turn off registration mode // (and the authentication method will be forgotten, if any, and if not verified) expiration : Timestamp; }; type AuthnMethodConfirmationCode = record { confirmation_code : text; expiration : Timestamp; }; type AuthnMethodSessionInfo = record { name : opt text; created_at : opt Timestamp; }; type RegistrationId = text; type AuthnMethodRegisterError = variant { // Authentication method registration mode is off, either due to timeout or because it was never enabled. RegistrationModeOff; // There is another authentication method already registered that needs to be confirmed first. RegistrationAlreadyInProgress; // The metadata of the provided authentication method contains invalid entries. InvalidMetadata : text; // The caller's principal is not self-authenticating. NotSelfAuthenticating : principal; // Passkey with this public key is already used PasskeyWithThisPublicKeyIsAlreadyUsed; }; type AuthnMethodConfirmationError = variant { Unauthorized : principal; InternalCanisterError : text; // Wrong confirmation code entered. Retry with correct code. WrongCode : record { retries_left : nat8; }; // Authentication method registration mode is off, either due to timeout or because it was never enabled. RegistrationModeOff; // There is no registered authentication method to be confirmed. NoAuthnMethodToConfirm; }; type AuthnMethodRegistrationModeEnterError = variant { InvalidRegistrationId : text; Unauthorized : principal; AlreadyInProgress; InternalCanisterError : text; }; type AuthnMethodRegistrationModeExitError = variant { Unauthorized : principal; InternalCanisterError : text; RegistrationModeOff; InvalidMetadata : text; PasskeyWithThisPublicKeyIsAlreadyUsed; }; type LookupByRegistrationIdError = variant { InvalidRegistrationId : text; }; type IdentityAuthnInfo = record { authn_methods : vec AuthnMethod; recovery_authn_methods : vec AuthnMethod; }; type IdentityInfo = record { authn_methods : vec AuthnMethodData; authn_method_registration : opt AuthnMethodRegistrationInfo; openid_credentials : opt vec OpenIdCredential; // Authentication method independent metadata metadata : MetadataMapV2; name : opt text; // The timestamp at which the anchor was created created_at : opt Timestamp; }; type IdentityInfoError = variant { // The principal is not authorized to call this method with the given arguments. Unauthorized : principal; // Internal canister error. See the error message for details. InternalCanisterError : text; }; type AuthnMethodAddError = variant { InvalidMetadata : text; }; type AuthnMethodReplaceError = variant { InvalidMetadata : text; // No authentication method found with the given public key. AuthnMethodNotFound; // Passkey with this public key is already used PasskeyWithThisPublicKeyIsAlreadyUsed; }; type AuthnMethodMetadataReplaceError = variant { InvalidMetadata : text; // No authentication method found with the given public key. AuthnMethodNotFound; }; type AuthnMethodSecuritySettingsReplaceError = variant { // No authentication method found with the given public key. AuthnMethodNotFound; }; type IdentityMetadataReplaceError = variant { // The principal is not authorized to call this method with the given arguments. Unauthorized : principal; // The identity including the new metadata exceeds the maximum allowed size. StorageSpaceExceeded : record { space_available : nat64; space_required : nat64; }; // Internal canister error. See the error message for details. InternalCanisterError : text; }; type CreateAccountError = variant { InternalCanisterError : text; AccountLimitReached; Unauthorized : principal; NameTooLong; }; type UpdateAccountError = variant { InternalCanisterError : text; AccountLimitReached; Unauthorized : principal; NameTooLong; }; type AccountDelegationError = variant { InternalCanisterError : text; Unauthorized : principal; NoSuchDelegation; }; type GetDefaultAccountError = variant { InternalCanisterError : text; Unauthorized : principal; NoSuchAnchor; NoSuchOrigin : record { anchor_number : UserNumber; }; }; type SetDefaultAccountError = variant { InternalCanisterError : text; Unauthorized : principal; NoSuchAnchor; NoSuchOrigin : record { anchor_number : UserNumber; }; NoSuchAccount : record { anchor_number : UserNumber; origin : FrontendHostname; }; }; type PrepareAccountDelegation = record { user_key : UserKey; expiration : Timestamp; }; type GetAccountsError = variant { InternalCanisterError : text; Unauthorized : principal; }; type PrepareIdAliasRequest = record { // Origin of the issuer in the attribute sharing flow. issuer : FrontendHostname; // Origin of the relying party in the attribute sharing flow. relying_party : FrontendHostname; // Identity for which the IdAlias should be generated. identity_number : IdentityNumber; }; type PrepareIdAliasError = variant { // The principal is not authorized to call this method with the given arguments. Unauthorized : principal; // Internal canister error. See the error message for details. InternalCanisterError : text; }; // The prepared id alias contains two (still unsigned) credentials in JWT format, // certifying the id alias for the issuer resp. the relying party. type PreparedIdAlias = record { rp_id_alias_jwt : text; issuer_id_alias_jwt : text; canister_sig_pk_der : PublicKey; }; // The request to retrieve the actual signed id alias credentials. // The field values should be equal to the values of corresponding // fields from the preceding `PrepareIdAliasRequest` and `PrepareIdAliasResponse`. type GetIdAliasRequest = record { rp_id_alias_jwt : text; issuer : FrontendHostname; issuer_id_alias_jwt : text; relying_party : FrontendHostname; identity_number : IdentityNumber; }; type GetIdAliasError = variant { // The principal is not authorized to call this method with the given arguments. Unauthorized : principal; // The credential(s) are not available: may be expired or not prepared yet (call prepare_id_alias to prepare). NoSuchCredentials : text; // Internal canister error. See the error message for details. InternalCanisterError : text; }; // The signed id alias credentials for each involved party. type IdAliasCredentials = record { rp_id_alias_credential : SignedIdAlias; issuer_id_alias_credential : SignedIdAlias; }; type SignedIdAlias = record { credential_jws : text; id_alias : principal; id_dapp : principal; }; type IdRegNextStepResult = record { // The next step in the registration flow next_step : RegistrationFlowNextStep; }; type IdRegStartError = variant { // The method was called anonymously, which is not supported. InvalidCaller; // Too many registrations. Please try again later. RateLimitExceeded; // A registration flow is already in progress. AlreadyInProgress; }; // The next step in the registration flow: // - CheckCaptcha: supply the solution to the captcha using `check_captcha` // - Finish: finish the registration using `identity_registration_finish` type RegistrationFlowNextStep = variant { // Supply the captcha solution using check_captcha CheckCaptcha : record { captcha_png_base64 : text; }; // Finish the registration using identity_registration_finish Finish; }; type CheckCaptchaArg = record { solution : text; }; type CheckCaptchaError = variant { // The supplied solution was wrong. Try again with the new captcha. WrongSolution : record { new_captcha_png_base64 : text; }; // This call is unexpected, see next_step. UnexpectedCall : record { next_step : RegistrationFlowNextStep; }; // No registration flow ongoing for the caller. NoRegistrationFlow; }; type IdRegFinishArg = record { authn_method : AuthnMethodData; name : opt text; }; type IdRegFinishResult = record { identity_number : nat64; }; type IdRegFinishError = variant { // This call is unexpected, see next_step. UnexpectedCall : record { next_step : RegistrationFlowNextStep; }; // No registration flow ongoing for the caller. NoRegistrationFlow; // The supplied authn_method is not valid. InvalidAuthnMethod : text; // Error while persisting the new identity. StorageError : text; }; type AccountInfo = record { // Null is unreserved default account account_number : opt AccountNumber; origin : text; last_used : opt Timestamp; // Configurable properties name : opt text; }; type AccountUpdate = record { name : opt text; }; type DummyAuthConfig = record { // Prompts user for a index value (0 - 255) when set to true, // this is used in e2e to have multiple dummy auth identities. prompt_for_index : bool; }; type IdentityPropertiesReplace = record { name : opt text; }; type IdentityPropertiesReplaceError = variant { Unauthorized : principal; StorageSpaceExceeded : record { space_available : nat64; space_required : nat64; }; NameTooLong : record { limit : nat64; }; InternalCanisterError : text; }; type PrepareAttributeRequest = record { // Identity for which the attributes should be prepared. identity_number : IdentityNumber; // Origin of the relying party in the attribute sharing flow. origin : FrontendHostname; // II account for the relying party. account_number : opt AccountNumber; // The attributes to be prepared. Each key has the form // `:`, where `` is either // `openid:` (e.g. `openid:https://accounts.google.com:email`) // or `sso:` (e.g. `sso:dfinity.org:email`). // // Each linked credential is addressable via exactly one scope: // credentials obtained through a `DiscoverableOidcConfig` (two-hop SSO // discovery) are reachable only via `sso:`; credentials from // hardcoded OIDC providers (Google, Microsoft, …) are reachable only via // `openid:`. Under `sso:` only `email` and `name` are supported; // under `openid:` `email`, `name`, and `verified_email` are supported. attribute_keys : vec text; }; type GetAccountError = variant { NoSuchOrigin : record { anchor_number : UserNumber; }; NoSuchAccount : record { anchor_number : UserNumber; origin : FrontendHostname; }; }; type PrepareAttributeError = variant { ValidationError : record { problems : vec text; }; AuthorizationError : principal; GetAccountError : GetAccountError; }; type PrepareAttributeResponse = record { issued_at_timestamp_ns : Timestamp; attributes : vec record { text; blob }; }; type GetAttributesRequest = record { // Identity for which the attributes should be prepared. identity_number : IdentityNumber; // Origin of the relying party in the attribute sharing flow. origin : FrontendHostname; // II account for the relying party. account_number : opt AccountNumber; // Timestamp received from the prepare_attributes call. issued_at_timestamp_ns : Timestamp; // The attribute to be retrieved, must be a subset of certified_attributes from // the prepare_attributes response. attributes : vec record { text; blob }; }; type CertifiedAttribute = record { key : text; value : blob; signature : blob; }; type CertifiedAttributes = record { expires_at_timestamp_ns : Timestamp; certified_attributes : vec CertifiedAttribute; }; type GetAttributesError = variant { ValidationError : record { problems : vec text; }; AuthorizationError : principal; GetAccountError : GetAccountError; }; // ICRC-3 attribute sharing types // ============================== type Icrc3Value = variant { Nat : nat; Int : int; Blob : blob; Text : text; Array : vec Icrc3Value; Map : vec record { text; Icrc3Value }; }; // A specification of an attribute to be certified. type AttributeSpec = record { // `:` where `` is // either `openid:` or `sso:`. // // Examples: // - `openid:https://accounts.google.com:email` // - `sso:dfinity.org:email` key : text; // If `value` is set, this attribute should be certified only if it matches // the current value. This enables the II frontend to request a certificate // for a set of attributes that is guaranteed to be approved by the user. value : opt blob; // Whether the attribute scope should be omitted before certification. // Certifying unscoped attributes is useful, e.g., when the user wants // to share their preferred email without revealing which OpenID // provider they use with II. // // Examples (e.g., `key = "openid:https://accounts.google.com:email"`): // 1. If `omit_scope = true`, then the certified attribute key is `email`. // 2. Otherwise, the certified attribute key is literally the value of `key`. omit_scope : bool; }; type PrepareIcrc3AttributeRequest = record { // Identity for which the attributes should be prepared. identity_number : IdentityNumber; // Origin of the relying party in the attribute sharing flow. May have // been remapped from `.icp0.io` to `.ic0.app` for principal // stability — see `unmapped_origin`. origin : FrontendHostname; // The relying party's actual origin, before the legacy `icp0.io → // ic0.app` remap that `origin` may have gone through. When set, this // value is what gets certified as `implicit:origin` instead of `origin`, // so that an RP signed in via the icp0.io domain sees its real origin // in the certified message. The canister verifies that mapping // `unmapped_origin` through the same legacy remap yields `origin`, // so an RP can't certify an arbitrary value here. unmapped_origin : opt FrontendHostname; // II account for the relying party. account_number : opt AccountNumber; // The attributes to be certified. attributes : vec AttributeSpec; // The nonce is a 32-byte value generated by the relying party. // The purpose of the nonce is to prevent replay attacks and // enable the relying party to expire attributes issued for a given flow. // The value of the nonce will be included into the signed ICRC-3 // message as a separate attribute with the key `implicit:nonce`. nonce : blob; }; type PrepareIcrc3AttributeResponse = record { // Candid-encoded ICRC-3 Value map. Pass this to get_icrc3_attributes. message : blob; }; type PrepareIcrc3AttributeError = variant { ValidationError : record { problems : vec text; }; AuthorizationError : principal; GetAccountError : GetAccountError; AttributeMismatch : record { problems : vec text; }; }; type GetIcrc3AttributeRequest = record { // Identity for which the attributes were prepared. identity_number : IdentityNumber; // Origin of the relying party in the attribute sharing flow. origin : FrontendHostname; // II account for the relying party. account_number : opt AccountNumber; // The message blob from PrepareIcrc3AttributeResponse. message : blob; }; type GetIcrc3AttributeResponse = record { signature : blob; }; type GetIcrc3AttributeError = variant { ValidationError : record { problems : vec text; }; AuthorizationError : principal; GetAccountError : GetAccountError; NoSuchSignature; }; // List available attributes type ListAvailableAttributesRequest = record { // Identity for which available attributes should be listed. identity_number : IdentityNumber; // Optional list of attribute keys to filter by. // Each key is either a fully-scoped key (e.g., // `"openid:https://accounts.google.com:email"` or // `"sso:dfinity.org:email"`) or an unscoped attribute name (e.g., // `"email"`) which matches all scopes. // If not provided, all available attributes are returned. attributes : opt vec text; }; type ListAvailableAttributesResponse = vec record { text; blob }; type ListAvailableAttributesError = variant { ValidationError : record { problems : vec text; }; AuthorizationError : principal; }; service : (opt InternetIdentityInit) -> { // Legacy identity management API // ============================== create_challenge : () -> (Challenge); register : (DeviceData, ChallengeResult, opt principal) -> (RegisterResponse); add : (UserNumber, DeviceData) -> (); update : (UserNumber, DeviceKey, DeviceData) -> (); // Atomically replace device matching the device key with the new device data replace : (UserNumber, DeviceKey, DeviceData) -> (); remove : (UserNumber, DeviceKey) -> (); // Returns all devices of the user (authentication and recovery) but no information about device registrations. // Note: Clears out the 'alias' fields on the devices. Use 'get_anchor_info' to obtain the full information. // Deprecated: Use 'get_anchor_credentials' instead. lookup : (UserNumber) -> (vec DeviceData) query; get_anchor_credentials : (UserNumber) -> (AnchorCredentials) query; get_anchor_info : (UserNumber) -> (IdentityAnchorInfo); get_principal : (UserNumber, FrontendHostname) -> (principal) query; enter_device_registration_mode : (UserNumber) -> (Timestamp); exit_device_registration_mode : (UserNumber) -> (); add_tentative_device : (UserNumber, DeviceData) -> (AddTentativeDeviceResponse); verify_tentative_device : (UserNumber, verification_code : text) -> (VerifyTentativeDeviceResponse); // V2 Identity Management API // ========================== // WARNING: The following methods are experimental and may ch 0ange in the future. // Starts the identity registration flow to create a new identity. identity_registration_start : () -> (variant { Ok : IdRegNextStepResult; Err : IdRegStartError }); // Check the captcha challenge // If successful, the registration can be finished with `identity_registration_finish`. check_captcha : (CheckCaptchaArg) -> (variant { Ok : IdRegNextStepResult; Err : CheckCaptchaError }); // Starts the identity registration flow to create a new identity. identity_registration_finish : (IdRegFinishArg) -> (variant { Ok : IdRegFinishResult; Err : IdRegFinishError }); // Returns information about the authentication methods of the identity with the given number. // Only returns the minimal information required for authentication without exposing any metadata such as aliases. identity_authn_info : (IdentityNumber) -> (variant { Ok : IdentityAuthnInfo; Err }) query; // Returns information about the identity with the given number. // Requires authentication. identity_info : (IdentityNumber) -> (variant { Ok : IdentityInfo; Err : IdentityInfoError }); // Replaces the authentication method independent metadata map. // The existing metadata map will be overwritten. // Requires authentication. identity_metadata_replace : (IdentityNumber, MetadataMapV2) -> (variant { Ok; Err : IdentityMetadataReplaceError }); // Replaces the identity properties. // The existing properties will be overwritten. // Requires authentication. identity_properties_replace : (IdentityNumber, IdentityPropertiesReplace) -> (variant { Ok; Err : IdentityPropertiesReplaceError }); // Adds a new authentication method to the identity. // Requires authentication. authn_method_add : (IdentityNumber, AuthnMethodData) -> (variant { Ok; Err : AuthnMethodAddError }); // Atomically replaces the authentication method matching the supplied public key with the new authentication method // provided. // Requires authentication. authn_method_replace : (IdentityNumber, PublicKey, AuthnMethodData) -> (variant { Ok; Err : AuthnMethodReplaceError }); // Replaces the authentication method metadata map. // The existing metadata map will be overwritten. // Requires authentication. authn_method_metadata_replace : (IdentityNumber, PublicKey, MetadataMapV2) -> (variant { Ok; Err : AuthnMethodMetadataReplaceError }); // Replaces the authentication method security settings. // The existing security settings will be overwritten. // Requires authentication. authn_method_security_settings_replace : (IdentityNumber, PublicKey, AuthnMethodSecuritySettings) -> (variant { Ok; Err : AuthnMethodSecuritySettingsReplaceError }); // Removes the authentication method associated with the public key from the identity. // Requires authentication. authn_method_remove : (IdentityNumber, PublicKey) -> (variant { Ok; Err }); // Enters the authentication method registration mode for the identity. // In this mode, a new authentication method can be registered, which then needs to be // confirmed before it can be used for authentication on this identity. // The registration mode is automatically exited after the returned expiration timestamp. // Requires authentication. authn_method_registration_mode_enter : (IdentityNumber, opt RegistrationId) -> (variant { Ok : record { expiration : Timestamp }; Err : AuthnMethodRegistrationModeEnterError }); // Exits the authentication method registration mode for the identity. // Requires authentication. authn_method_registration_mode_exit : (IdentityNumber, opt AuthnMethodData) -> (variant { Ok; Err : AuthnMethodRegistrationModeExitError }); // Registers a new authentication method to the identity. // This authentication method needs to be confirmed before it can be used for authentication on this identity. authn_method_register : (IdentityNumber, AuthnMethodData) -> (variant { Ok : AuthnMethodConfirmationCode; Err : AuthnMethodRegisterError }); // Registers a new session for the identity. // This session needs to be confirmed before it can be used to register an authentication method on this identity. authn_method_session_register : (IdentityNumber) -> (variant { Ok : AuthnMethodConfirmationCode; Err : AuthnMethodRegisterError }); // Returns session info when session is confirmed and caller matches session. authn_method_session_info : (IdentityNumber) -> (opt AuthnMethodSessionInfo) query; // Confirms a previously registered authentication method. // On successful confirmation, the authentication method is permanently added to the identity and can // subsequently be used for authentication for that identity. // Requires authentication. authn_method_confirm : (IdentityNumber, confirmation_code : text) -> (variant { Ok; Err : AuthnMethodConfirmationError }); lookup_by_registration_mode_id : (RegistrationId) -> (opt IdentityNumber) query; // Authentication protocol // ======================= prepare_delegation : (UserNumber, FrontendHostname, SessionKey, maxTimeToLive : opt nat64) -> (UserKey, Timestamp); get_delegation : (UserNumber, FrontendHostname, SessionKey, Timestamp) -> (GetDelegationResponse) query; // Attribute sharing protocol // ========================== prepare_attributes : (PrepareAttributeRequest) -> (variant { Ok : PrepareAttributeResponse; Err : PrepareAttributeError }); get_attributes : (GetAttributesRequest) -> (variant { Ok : CertifiedAttributes; Err : GetAttributesError }) query; // ICRC-3 Attribute sharing protocol // ================================== prepare_icrc3_attributes : (PrepareIcrc3AttributeRequest) -> (variant { Ok : PrepareIcrc3AttributeResponse; Err : PrepareIcrc3AttributeError }); get_icrc3_attributes : (GetIcrc3AttributeRequest) -> (variant { Ok : GetIcrc3AttributeResponse; Err : GetIcrc3AttributeError }) query; list_available_attributes : (ListAvailableAttributesRequest) -> (variant { Ok : ListAvailableAttributesResponse; Err : ListAvailableAttributesError }) query; // Old Verifiable Credentials API // ============================== // The methods below are used to generate ID-alias credentials during attribute sharing flow. prepare_id_alias : (PrepareIdAliasRequest) -> (variant { Ok : PreparedIdAlias; Err : PrepareIdAliasError }); get_id_alias : (GetIdAliasRequest) -> (variant { Ok : IdAliasCredentials; Err : GetIdAliasError }) query; // OpenID credentials protocol // =========================== openid_identity_registration_finish : (OpenIDRegFinishArg) -> (variant { Ok : IdRegFinishResult; Err : IdRegFinishError }); openid_credential_add : (IdentityNumber, JWT, Salt) -> (variant { Ok; Err : OpenIdCredentialAddError }); openid_credential_remove : (IdentityNumber, OpenIdCredentialKey) -> (variant { Ok; Err : OpenIdCredentialRemoveError }); openid_prepare_delegation : (JWT, Salt, SessionKey) -> (variant { Ok : OpenIdPrepareDelegationResponse; Err : OpenIdDelegationError }); openid_get_delegation : (JWT, Salt, SessionKey, Timestamp) -> (variant { Ok : SignedDelegation; Err : OpenIdDelegationError }) query; // HTTP Gateway protocol // ===================== http_request : (request : HttpRequest) -> (HttpResponse) query; // OIDC Discovery // =============== discovered_oidc_configs : () -> (vec OidcConfig) query; add_discoverable_oidc_config : (DiscoverableOidcConfig) -> (); // Internal Methods // ================ init_salt : () -> (); stats : () -> (InternetIdentityStats) query; config : () -> (InternetIdentityInit) query; whoami : () -> (principal) query; deploy_archive : (wasm : blob) -> (DeployArchiveResult); // Returns a batch of entries _sorted by sequence number_ to be archived. // This is an update call because the archive information _must_ be certified. // Only callable by this IIs archive canister. fetch_entries : () -> (vec BufferedArchiveEntry); acknowledge_entries : (sequence_number : nat64) -> (); // Discoverable passkeys protocol lookup_device_key : (credential_id : blob) -> (opt DeviceKeyWithAnchor) query; // Multiple accounts get_accounts : ( anchor_number : UserNumber, origin : FrontendHostname, ) -> (variant { Ok : vec AccountInfo; Err: GetAccountsError }) query; create_account : ( anchor_number : UserNumber, origin : FrontendHostname, name : text ) -> (variant { Ok : AccountInfo; Err: CreateAccountError }); update_account : ( anchor_number : UserNumber, origin : FrontendHostname, account_number : opt AccountNumber, // Null is unreserved default account update : AccountUpdate ) -> (variant { Ok : AccountInfo; Err: UpdateAccountError }); prepare_account_delegation : ( anchor_number : UserNumber, origin : FrontendHostname, account_number : opt AccountNumber, // Null is unreserved default account session_key : SessionKey, max_ttl : opt nat64 ) -> (variant { Ok : PrepareAccountDelegation; Err : AccountDelegationError }); get_account_delegation : ( anchor_number : UserNumber, origin : FrontendHostname, account_number : opt AccountNumber, // Null is unreserved default account session_key : SessionKey, expiration : Timestamp ) -> (variant { Ok : SignedDelegation; Err : AccountDelegationError }) query; get_default_account : ( anchor_number : UserNumber, origin : FrontendHostname, ) -> (variant { Ok : AccountInfo; Err: GetDefaultAccountError }) query; set_default_account : ( anchor_number : UserNumber, origin : FrontendHostname, account_number : opt AccountNumber ) -> (variant { Ok : AccountInfo; Err: SetDefaultAccountError }); // Looks up identity number when called with a recovery phrase lookup_caller_identity_by_recovery_phrase : () -> (opt IdentityNumber); };