Dynamic client registration
POST https://sso.user.m7.org/register
Content-Type: application/json
Authorization: Bearer ACCESS_TOKEN
Dynamic registration creates an active personal OAuth client for the M7
principal represented by the access token, unless the request explicitly
selects an organization that principal may manage. It is suitable for
developer tooling and self-service application setup. First complete a user
sign-in to obtain that access token, then call /register. Use the
M7 User API
to manage a registered client's later configuration, status, or deletion.
For app-owned tenant sign-in screens, register an organization-owned application then configure the explicit browser-direct allowances through API User/User M7. Follow browser-direct setup for callback origins and mandatory proofs; these policy switches are not additional Dynamic Registration metadata advertised by this page.
The endpoint uses the JSON request/response format defined by
OAuth Dynamic Client Registration (RFC 7591)
and OpenID Connect Registration.
M7-specific metadata is identified below; response_modes is an optional M7
extension, distinct from the standard response_types registration field.
The request must be JSON and must use an active M7 access token. The current
registration contract uses Authorization: Bearer ACCESS_TOKEN; requests
without a valid token and any binding material required by that credential
fail with invalid_token. The standard dpop_bound_access_tokens client
metadata controls the new client's DPoP requirement independently of the
credential used to authorize registration. See the
project-specific DPoP status.
Minimal public client
The minimal request creates a public web client enabled for authorization code flow:
curl --fail-with-body --silent --show-error \
--request POST 'https://sso.user.m7.org/register' \
--header 'Authorization: Bearer ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"client_name": "Example App",
"redirect_uris": ["https://app.example.com/oauth/callback"],
"token_endpoint_auth_method": "none"
}'
M7 requires at least one HTTPS redirect_uris entry. Redirect URIs are exact
values, not patterns. The registration endpoint does not permit HTTP loopback
or custom-scheme exceptions; use a registered HTTPS redirect URI.
Request metadata
| Field | Required | Rules |
|---|---|---|
redirect_uris |
Yes | Array of one or more unique HTTPS URLs. |
client_name |
No | Display name. Defaults from the first redirect URI host when omitted. |
application_type |
No | web (default), native, or spa. |
response_types |
No | Omit or set to ['code']; no other response type is supported. |
response_modes |
No | M7 extension: JSON array of authorization response-mode names. Omission or [] registers ["query"]. See Response modes. |
authorization_signed_response_alg |
No | Standard JARM metadata: exactly RS256 or RS512; omission defaults to RS256. The effective value is returned. It is independent of ID-token, UserInfo and client-authentication algorithms. |
grant_types |
No | Defaults to ['authorization_code']. Allowed values: authorization_code, refresh_token, client_credentials, urn:ietf:params:oauth:grant-type:device_code, and urn:ietf:params:oauth:grant-type:token-exchange. See connection configuration for exchange prerequisites and deployment status. |
scope |
No | Space-delimited string of allowed scopes. Scope names are case-sensitive; malformed or non-string values are rejected. |
tenant |
No | Organization UUID. Omit it for personal ownership. When supplied, the authenticated principal must be allowed to manage that active, non-archived organization. |
token_endpoint_auth_method |
No | client_secret_basic (default), none, client_secret_post, client_secret_jwt, private_key_jwt, tls_client_auth, or self_signed_tls_client_auth. Request none explicitly for a public client. |
client_secret |
No | Optional caller-selected secret for a secret-based method or HS256/384/512 token signing. M7 generates one when omitted; HMAC needs at least 32/48/64 bytes respectively. |
post_logout_redirect_uris |
No | Array of exact HTTPS URLs allowed for end-session return. |
frontchannel_logout_uri |
No | Optional logout notification endpoint. HTTPS URL, at most 2048 characters, without credentials or a fragment; scheme, host and port must match a registered redirect URI. |
frontchannel_logout_session_required |
No | JSON boolean; defaults to false. true requires a configured front-channel URL. |
backchannel_logout_uri |
No | Optional logout notification endpoint. HTTPS URL, at most 2048 characters, without credentials or a fragment. A separate host/port and query parameters are permitted. |
backchannel_logout_session_required |
No | JSON boolean; defaults to false. true requires a configured back-channel URL. |
initiate_login_uri |
No | Application's HTTPS login-start URL. M7 can use it after an expired PAR request. |
default_max_age |
No | Non-negative integer default authentication age in seconds. |
require_auth_time |
No | Boolean; defaults to false. When true, every ID token for the client must include the standard auth_time claim. This does not itself force reauthentication. |
id_token_signed_response_alg |
No | Available for issuance: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, ES256K, Ed25519, Ed448, ML-DSA-44, ML-DSA-65, ML-DSA-87. Omission defaults to RS256; spelling is normalized and the effective value is returned. HS256, HS384, and HS512 are also supported with a recoverable client secret; see HMAC setup. |
userinfo_signed_response_alg |
No | RS256 or RS512. When present, /userinfo returns a signed JWT using that algorithm. Omission retains ordinary JSON. |
dpop_bound_access_tokens |
No | Boolean; defaults to false. true requires a valid DPoP proof on every token request. false or omission still permits a client to request an opportunistically DPoP-bound token by sending a valid proof. |
token_endpoint_auth_signing_alg |
Conditional | Signing algorithm for client_secret_jwt or private_key_jwt. Omission selects HS256 or RS256, respectively. |
jwks_uri |
Conditional | Public HTTPS JWKS URL for key-based authentication or the response-encryption policy below; mutually exclusive with jwks. |
jwks |
Conditional | Inline public JWK Set for key-based authentication or the response-encryption policy below; mutually exclusive with jwks_uri. |
tls_client_auth_subject_dn |
Conditional | Exact certificate subject DN selector for tls_client_auth; use exactly one subject-DN or SAN selector. |
tls_client_auth_san_dns |
Conditional | Exact DNS SAN selector for tls_client_auth. |
tls_client_auth_san_uri |
Conditional | Exact URI SAN selector for tls_client_auth. |
tls_client_auth_san_ip |
Conditional | Exact IP-address SAN selector for tls_client_auth. |
tls_client_auth_san_email |
Conditional | Exact email SAN selector for tls_client_auth. |
tls_client_certificate_bound_access_tokens |
Conditional | Boolean valid only with an mTLS authentication method; defaults to false. When true, issued access and refresh tokens are bound to the presented leaf certificate. |
Select an ID-token algorithm that is advertised by the live discovery document
and supported by the relying party's verifier. Both discovery documents
advertise all 18 profiles: 15 asymmetric plus HS256/384/512. This does not
upgrade existing SDKs. Updated M7 token-verifier source can use the optional
m7crypto backend, but current Web SDK full-token cookies are unsuitable for
general ML-DSA use; check SDK/key and storage compatibility
before changing an existing web app. The signing choice is independent of
userinfo_signed_response_alg, client-authentication assertions, and JAR.
Registration does not grant a resource audience. Before the client can obtain
tokens, an administrator must configure at least one exact
allowed_audiences value for it. When several audiences are configured, each
grant may request any nonempty subset; omission selects the complete configured
set where the grant permits omission.
Organization ownership is authorized again during draft creation,
authentication setup, and activation. Registration fails closed if the
organization is missing, inactive, archived, or no longer manageable by the
authenticated principal. The successful response includes tenant for an
organization-owned client and omits it for a personal registration.
Dynamic registration supports only web, native, and spa application
types. It cannot create an application_type=machine client; create and
manage machine applications through the M7 User API instead.
The registration request also accepts these optional client metadata fields:
client_uri, logo_uri, policy_uri, tos_uri, contacts, subject_type,
sector_identifier_uri, default_acr_values, software_id, and
software_version.
The following deferred protocol metadata is deliberately rejected with
invalid_client_metadata before client creation or modification:
request_object_signing_alg,request_object_encryption_alg, andrequest_object_encryption_enc; andrequest_uris.
Signed JAR is supported separately at /authorize for clients with an enabled
JAR Request Policy, configured through the M7 account application's OAuth
client settings. Dynamic Registration does not configure that policy: the
standard Request Object metadata listed above remains rejected. JAR signing
keys are distinct from this endpoint's token-authentication jwks or
jwks_uri. See Signed Request Objects
(JAR).
An M7-issued PAR request_uri remains valid at /authorize independently of
JAR policy.
URL-bearing metadata must be valid URLs. jwks_uri and the URL configuration
fields that represent security metadata must use HTTPS.
Authentication metadata is validated as one closed combination before client
creation. client_secret_jwt accepts only HS256, HS384, or HS512 and
requires a usable secret. private_key_jwt accepts only RS256, RS384,
RS512, or ES256 and requires exactly one of jwks_uri or jwks.
JWT authentication fields on none, Basic, or POST registrations, incompatible
algorithms and incomplete key sources are rejected with
invalid_client_metadata without leaving an active client. A client_secret
on private-key JWT or mTLS is permitted when HS token signing is selected;
it serves HMAC and does not change the authentication method. SSO rejects
HS token signing with none as invalid_client_metadata before creating a
registration in the locally tested eligibility update described below;
production verification of that update remains pending.
tls_client_auth requires exactly one of the five subject-DN/SAN selector
fields. self_signed_tls_client_auth requires exactly one of jwks_uri or
jwks, and each usable key must represent a self-signed certificate through
its public x5c certificate chain. Private JWK members are rejected. The
certificate-bound-token boolean is valid only with one of these two methods.
After registration, use the mTLS operation aliases published by discovery;
the issuer and browser authorization endpoint do not change.
Before registering client_secret_jwt, configure the same
M7_OAUTH_CLIENT_SECRET_JWT_KEYS value on API User and SSO. HMAC token signing
also requires the same ring on ID.M7. New secrets are
encrypted with the first 64-character hexadecimal key; remaining keys permit
rolling decryption. A legacy password-hash row is deliberately not accepted as
an HMAC key and requires secret reissue.
Logout notification metadata configures logout delivery
for participating applications. Delivery is deployed and advertised; saving a URL
alone does not send notifications or invalidate application sessions. M7 always
sends sid on both channels and iss on the front channel, even when the standard
session-required booleans are false or absent. They express receiver requirements,
not a send/omit option.
User.M7 shows the URL fields under Client → Logout only when editing an existing
application, with a separate save action and no session-ID checkboxes. These
receivers are independent of post_logout_redirect_uris, which remain under
General. Dynamic Registration can supply the notification fields at creation.
Blank or null notification URLs remain unconfigured. False session requirements use sparse storage; supplied flags must be JSON booleans. For each configured channel, the registration response returns the stored URL and effective boolean. Unconfigured channels are omitted. Stored values are checked after policy setup and before/after activation; a mismatch fails registration and triggers cleanup.
HMAC token signing
Select HS256, HS384 or HS512 in id_token_signed_response_alg. In M7 this
preference also controls application access and refresh token signing. When
editing an existing app, first configure and save confidential-client
authentication on the Auth page. Then save the HMAC algorithm and set/reset
its secret on the Auth page or through API User's
POST /api/v2/oauth/clients/set_auth.
Dynamic Registration instead accepts a suitable supplied secret or generates
one, returning it once in the successful response.
Use randomly generated original secrets of at least 32 bytes for HS256,
48 for HS384 or 64 for HS512. The same value serves HMAC and Basic, POST or
secret-JWT authentication when both apply. With private-key JWT or mTLS, the
stored HMAC secret does not change the authentication method. Public clients
using none must choose an asymmetric signing algorithm. A browser or native
application does not become confidential merely by embedding a static secret.
The 2026-09-16 eligibility restriction is implemented and locally tested;
production deployment verification remains pending. User.M7 prevents the
none/HMAC combination using saved settings, while keeping an existing invalid
selection visible for repair. Dynamic Registration returns HTTP 400
invalid_client_metadata; supplying a secret does not make none eligible.
SSO returns HTTP 400 with
unauthorized_client at PAR, device authorization and /token, including
code pickup and refresh, before consuming grant artifacts. Existing invalid
records require an explicit configuration repair; there is no automatic
algorithm change or credential revocation. To change an HMAC client to
none, first choose and save an asymmetric algorithm. Shared secret storage,
signing services and the advertised algorithm inventory remain available.
Direct API User management retains the underlying storage support and can still save this combination; it does not make the configuration eligible at SSO. For an existing public client, save an asymmetric algorithm and start a new sign-in where a new signing lineage is needed. Configure confidential authentication only when the actual client can protect its credentials; changing the method label alone does not establish confidentiality. This restriction does not revoke previously issued credentials or replace their normal expiry and revocation controls.
HMAC requires recoverable encrypted storage. Existing Basic/POST password hashes cannot be converted into signing keys. Missing, empty, hashed, unreadable or undersized secrets fail before issuance; save a suitable secret before retrying. M7 never downgrades to another algorithm. A pre-existing personal asymmetric refresh lineage cannot switch families in place; start a new sign-in after changing it to HMAC. Root credentials remain asymmetric.
HMAC has no public certificate or PEM/JWK/JWKS lookup. Never expose the secret to browser JavaScript. A secret holder can both verify and create MACs, so local MAC validation alone does not prove provider issuance or active state. M7 additionally checks the issued token's recorded hash; resource consumers must retain authoritative issued-token/state checks, such as applicable introspection, plus claims, scope, token-class and sender constraints. Retain an old secret while accepting old tokens after rotation. ID tokens are relying-party assertions, not API credentials; refresh tokens remain opaque client state.
HS256/384/512 passed client-credentials, consumer device-code/strict-refresh
and browser authorization-code/PAR login, profile and strict-refresh campaigns
in September 2026. Browser tests included PKCE and DPoP. Basic/Post
introspection, revocation and temporary-client cleanup passed. The historical
none device case verified signing mechanics; the eligibility restriction
above now excludes that combination and preserves confidential-client HMAC.
This does not claim every authentication method, refresh mode or live secret
rotation, nor formal OpenID conformance.
The Web SDK uses authenticated SSO introspection and passed without m7crypto.
Current Token/PHP source supports local HMAC through explicit hmac_secret
and the native extension; existing immutable SDK ZIPs are unchanged. See
SDK HMAC guidance.
Both live discovery documents advertise these HMAC algorithms with the
15 asymmetric profiles, verified at 2026-09-15 21:49:24 UTC. See
HMAC and discovery;
clients must follow live metadata for automatic negotiation.
UserInfo, JARM, JAR, DPoP and client-authentication assertions retain their
separate algorithm lists.
Response modes (M7 extension)
Register one or more modes through the same JSON request:
{
"client_name": "Example App",
"redirect_uris": ["https://app.example.com/oauth/callback"],
"response_types": ["code"],
"response_modes": ["query", "form_post"],
"token_endpoint_auth_method": "none"
}
The registration inventory is query, form_post, fragment, query.jwt,
form_post.jwt, fragment.jwt, jwt, web_message, web_message.opener,
and web_message.parent. Names are trimmed, lowercased and deduplicated.
- Omission or an empty JSON array registers
query. - A nonempty list replaces that default;
queryis not added automatically to a list such as["form_post"]. - The field must be a JSON array of strings. Null, strings (including
newline-separated text), objects, nested arrays, non-string entries, blank
names and unknown mode names produce
invalid_client_metadatabefore creating a client. - The successful response includes the modes actually saved by API.USER,
in stored lexical order. The endpoint verifies that this set matches the
normalized request before activation and again after activation. Missing,
malformed or changed backend metadata produces
server_errorand invokes registration cleanup.
All ten modes are implemented and advertised by live discovery. Register only
the modes the application can securely receive; each authorization request
selects one permitted mode. response_mode (singular) belongs to an individual
authorization request; response_modes (plural) is this M7 registration extension. Other
providers are not required to understand this extension.
For signed JARM, register a JWT mode and set
authorization_signed_response_alg to RS256 or RS512. The default is RS256
even when the field is omitted. Unsupported algorithms, none, null and
malformed values are rejected as invalid_client_metadata.
JARM encryption metadata is configured through the
response-encryption policy.
Registered response encryption is deployed; see the scoped live evidence in
response encryption. See
response delivery and validation.
Web Message registration does not grant iframe permission. The embedding origin also needs the provider's explicit framing allowance, and the client must satisfy the browser requirements.
Response-encryption policy
Registration accepts and forwards the following standard metadata to API User. SSO enforces required encryption for ID tokens, JARM and signed UserInfo. The inline-key RS256 browser path passed live login, refresh, UserInfo and cancellation acceptance on 2026-09-16. Confirm receiving SDK support before enabling a required policy. See response encryption for key selection and rollout.
| Response | Algorithm field | Content-encryption field |
|---|---|---|
| ID token | id_token_encrypted_response_alg |
id_token_encrypted_response_enc |
| JARM | authorization_encrypted_response_alg |
authorization_encrypted_response_enc |
| Signed UserInfo | userinfo_encrypted_response_alg |
userinfo_encrypted_response_enc |
For each selected response, set the algorithm to exactly RSA-OAEP-256 and
the content-encryption value to exactly A256GCM. Omit both fields to leave
that response's policy unset. Nulls, empty strings, partial pairs and other
algorithms produce HTTP 400 invalid_client_metadata before client creation.
OIDC and JARM default an omitted content-encryption value to A128CBC-HS256;
this profile does not implement that default and requires explicit A256GCM.
The inner signing algorithm remains independent. UserInfo encryption also
requires userinfo_signed_response_alg to be RS256 or RS512.
Supply exactly one standard public source, jwks or jwks_uri. For example,
merge this metadata with the usual registration request:
{
"jwks_uri": "https://app.example.com/.well-known/jwks.json",
"id_token_encrypted_response_alg": "RSA-OAEP-256",
"id_token_encrypted_response_enc": "A256GCM"
}
Encryption may be registered with any supported authentication method,
including none. Inline encryption keys must be public RSA keys with distinct
nonempty kid values, 2048–8192-bit moduli and compatible use, alg and
key_ops. Private/symmetric material and encryption-key URL/certificate
members are rejected. The inline set is limited to 32 keys and 64 KiB.
For private_key_jwt or self_signed_tls_client_auth, a combined inline set
must identify every key with use: sig for authentication, enc for
encryption. Each subset must satisfy its existing validator. Signing keys in
an encryption registration currently require one of those key-based auth
methods. A source without any encryption policy retains the existing
authentication-only registration rules.
Encryption jwks_uri must use a public DNS HTTPS hostname on port 443 with no
credentials, fragment, IP literal or local hostname. Registration checks URL
syntax without fetching it. At issuance, SSO fetches through its pinned HTTPS
boundary, validates the document and selects the encryption subset.
SSO forwards the public encryption source into API User's separate
response_encryption_jwks or response_encryption_jwks_uri configuration and
sends the six policy fields unchanged through oauth.clients.set_knobs.
Authentication retains its own key configuration. Successful registration
returns the standard six fields and jwks or jwks_uri; a mixed inline set
is reconstructed from both stored purposes. Internal source aliases are not
part of the public registration contract. Missing or changed backend settings
produce HTTP 502 server_error and trigger cleanup, with checks before and
after activation.
Configure the receiving application with the matching private key and required policy before enabling encryption. Registering a public key does not supply a private key or decryption implementation to your application. The field names follow OIDC Dynamic Client Registration and JARM client metadata.
Connection configuration (M7 extensions)
The following optional top-level fields store the same settings as User.M7's Knobs → Connections panel. Registration stores these settings; the token endpoint enforces them with the live connection and source authorization.
These settings control incoming connections and exchange policy for the
registered provider. closed rejects new connections without revoking existing
ones; unlisted permits requests by known client ID; discoverable also lists
the app's public name and client ID. Approval can be manual, automatic, or
automatic for the same registered owner. For organization apps, the owner is
the organization itself; the managing users never define the same-site boundary.
Personal apps match by their personal owner. Missing settings default to closed,
manual approval and exchange disabled.
| Field | JSON type and accepted values |
|---|---|
connection_policy_availability |
String: closed, unlisted, or discoverable. |
connection_policy_approval |
String: manual, same_site_auto, or auto. |
connection_policy_other_sites |
String: manual or reject; fallback for different owners under same_site_auto. |
connection_policy_token_exchange_enabled |
Boolean. Explicit false is stored and returned. |
connection_policy_token_exchange_approval |
String: manual or connection_policy; records separate approval or inclusion in connection approval. |
connection_policy_token_exchange_scopes |
Array of up to 100 scope strings, at most 256 bytes each, using OAuth scope-token characters. Duplicates are removed. [] leaves the setting absent. |
connection_policy_token_exchange_ttl_max |
Integer from 1 to 2147483647 seconds. |
Omit a field to leave it unconfigured. Null, empty strings, string booleans,
string TTLs and scope objects are rejected with invalid_client_metadata
before client creation. Preferences may be stored while exchange is disabled.
The scope ceiling is separate from the client's scope registration metadata;
neither it nor an absent ceiling grants resource authority.
{
"client_name": "Example connection configuration",
"redirect_uris": ["https://app.example.com/oauth/callback"],
"token_endpoint_auth_method": "client_secret_basic",
"grant_types": [
"authorization_code",
"urn:ietf:params:oauth:grant-type:token-exchange"
],
"connection_policy_availability": "unlisted",
"connection_policy_approval": "manual",
"connection_policy_other_sites": "reject",
"connection_policy_token_exchange_enabled": true,
"connection_policy_token_exchange_approval": "manual",
"connection_policy_token_exchange_scopes": ["files:read"],
"connection_policy_token_exchange_ttl_max": 600
}
The canonical Token Exchange URI is accepted in the standard grant_types
field. It permits the requesting app to use the grant; the provider's exchange
policy flag controls incoming exchange and does not add a grant. /token
implements the local-user, single-target exchange profile,
and both live discovery documents advertise the canonical grant. The consumer
exchange and refresh path passed scoped live acceptance on 2026-09-20.
In manual exchange-approval mode, the
provider must also approve exchange on the particular connection. In
connection_policy mode, the active connection supplies that approval.
Neither mode expands the user's signed scope authority. An absent exchange
scope ceiling permits nothing. The exchange TTL cap limits both access and
refresh lifetimes; refresh still requires explicit authorized offline_access.
Existing HTTPS redirect-URI and application-type requirements still apply,
including registrations containing only the exchange grant.
Successful responses include these fields from the saved configuration and
the saved grant list. SSO checks storage after saving policy, after client
authentication setup and after activation. Missing or changed values cause
HTTP 502 server_error and trigger deletion of the incomplete client, so a
backend that drops the new fields cannot report successful registration.
Confidential-client examples
Client secret
{
"client_name": "Example server app",
"redirect_uris": ["https://app.example.com/oauth/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"token_endpoint_auth_method": "client_secret_basic"
}
M7 returns client_secret once in the successful registration response if the
selected authentication method or HMAC token-signing choice needs one. Store it immediately in a
secret manager; do not expect the plaintext secret to be retrievable later.
Private-key JWT
{
"client_name": "Example private-key client",
"redirect_uris": ["https://app.example.com/oauth/callback"],
"token_endpoint_auth_method": "private_key_jwt",
"token_endpoint_auth_signing_alg": "ES256",
"jwks_uri": "https://app.example.com/.well-known/jwks.json"
}
For private_key_jwt, M7 selects the assertion key by kid from either the
registered inline JWKS or the registered HTTPS JWKS URL. The assertion must
use a configured supported signing algorithm and satisfy the token-endpoint
client assertion checks described in Token endpoint.
Successful response
M7 responds with HTTP 201, standard registration metadata and the M7
response_modes extension:
{
"client_id": "CLIENT_ID",
"client_id_issued_at": 1786309200,
"application_type": "web",
"client_name": "Example App",
"redirect_uris": ["https://app.example.com/oauth/callback"],
"response_types": ["code"],
"response_modes": ["query"],
"grant_types": ["authorization_code"],
"token_endpoint_auth_method": "none",
"dpop_bound_access_tokens": false
}
The response includes the submitted optional metadata that M7 accepted. A
secret-based or HMAC-signing registration additionally includes client_secret and
client_secret_expires_at (currently 0 for no fixed expiry).
Common errors
| Error | Typical cause |
|---|---|
invalid_token |
Missing, expired, revoked, or incorrectly bound bearer token. |
invalid_client_metadata |
Body is not a JSON object, has unsupported or malformed metadata (including response_modes), contains a malformed tenant, or selects an organization the principal cannot currently manage. |
invalid_redirect_uri |
Missing, malformed, non-HTTPS, or duplicate-invalid redirect URI data. |
server_error |
Registration could not reach or complete its management backend. |
Register consumer organization access
Register orgs in the consumer client's permitted scope set, request it
explicitly and obtain hosted consent before calling
consumer org discovery. Registration alone does not add
the scope to existing tokens. The same registered UserInfo signing/encryption
policy governs /userinfo/orgs; there is no per-request format override or
separate org response-policy flag. Tenant groups and primary-email email
remain separate permissions. Device authorization requires hosted
device consent before granting orgs.