Preview an organization policy

POST /v1/organizations/{org_id}/policies/{policy_kind}:preview · permission organizations:write

Evaluates a candidate settings object without saving it. The body is the same as for creating or replacing a policy, and the server checks it with the same rules and the same plan gate, so a candidate that PUT would reject is rejected here with the same problem code. Nothing is written: no policy, no audit entry and no event. The request takes no If-Match and no Idempotency-Key, and the response carries no ETag.

The response counts the users the candidate applies to (basis users_in_scope), not the users who would be blocked, with one exception: phishing_resistant (see below). Conditions that are only known at sign-in, or that the policy service does not hold, are not filtered out; not_evaluated lists them so that the count is never read as more than it is.

Kind Users counted not_evaluated
authentication_methods Active members of the organization credentials
mfa (required_for admins or all) Active members of the organization mfa_enrollment; also admin_scope for admins
phishing_resistant (required_for admins or all) Active members of the organization without an accepted WebAuthn credential (basis users_without_webauthn, see below) credential_policy; also admin_scope for admins
sso_enforcement org_context Active members of the organization, minus bypass_user_ids federated_sign_in
sso_enforcement verified_domains Active members, plus active users of the environment with an email address on a verified domain of this organization, minus bypass_user_ids federated_sign_in
session Active members of the organization none
ip_allowlist Active members of the organization client_ip; also admin_scope for admins

For phishing_resistant, the count and the sample are the users in scope who cannot sign in phishing-resistantly today: users without an active WebAuthn credential (a passkey, or a security key used with a first factor) that the AAGUID allowlist accepts. The allowlist is the candidate's, or the environment's when the candidate's is empty; with an allowlist, a credential counts only if its model is listed and its attestation was verified. Pending, revoked and clone-suspected credentials do not count. credential_policy means that the environment's attestation requirement, the device-bound passkey rule and the authenticator model status are not applied, so the count can be lower than the number of users who would be blocked. When the scope has more than 10,000 users, the response falls back to users_in_scope with passkey_enrollment. If the credential data cannot be read, the request fails with 503 and no count is returned.

required_for none and mode off count nobody. An active member is a member whose membership is active and whose user is not blocked; each user is counted once. admin_scope means that admins is counted as all members, which is how sign-in applies it today. The users of another organization or another environment are never counted.

Request

Field Type Required Description
org_id path yes Organization ID (org_…).
policy_kind path yes Policy kind: authentication_methods, mfa, phishing_resistant, sso_enforcement, session or ip_allowlist. Any other value returns 404.
settings object yes The candidate settings object of the kind, with the same fields as for PUT.

Request body:

{
  "settings": {
    "required_for": "all",
    "allowed_factors": [
      "totp",
      "webauthn"
    ],
    "enrollment_grace_days": 7
  }
}

Response

200 OK. sample holds at most 20 users of the counted set, ordered by ID, with the user ID only.

Field Type Description
organization_id string Organization ID (org_…).
policy_kind string The previewed kind.
basis string What affected_count counts: users_in_scope or, for phishing_resistant, users_without_webauthn. New values may be added.
affected_count integer Number of users that basis counts.
sample array At most 20 objects with user_id (usr_…).
not_evaluated array Conditions the count does not filter: admin_scope, credentials, mfa_enrollment, passkey_enrollment, federated_sign_in, client_ip, credential_policy. New values may be added.
{
  "organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
  "policy_kind": "mfa",
  "basis": "users_in_scope",
  "affected_count": 2,
  "sample": [
    {
      "user_id": "usr_01j9xk3m7q8r2s4t6v8w0y2z4b"
    },
    {
      "user_id": "usr_01j9xk3m7q8r2s4t6v8w0y2z4c"
    }
  ],
  "not_evaluated": [
    "mfa_enrollment"
  ]
}

Errors

HTTP code When
400 unknown_field The body has a field that is not in the schema.
403 plan_feature_unavailable The kind or the AAGUID allowlist requires a higher plan; the problem carries feature and required_plan.
404 not_found The organization does not exist or the kind is unknown.
409 domain_not_verified sso_enforcement with mode verified_domains needs a verified domain on the organization.
409 connection_test_required Turning sso_enforcement on (from off or from no policy) needs a successful test sign-in of the current configuration of at least one of the connection_ids in the last 24 hours. Run a connection test (POST /v1/connections/{connection_id}:test) and try again.
409 organization_pending_deletion The organization is waiting for self-service deletion.
422 validation_failed A settings field is unknown or invalid; errors[] points at /settings/….
422 policy_weaker_than_parent The setting is weaker than the environment's setting; errors[] points at the weaker field.
422 at_least_one_method authentication_methods leaves no sign-in method.
401 unauthenticated The credential is missing, invalid or revoked.
403 insufficient_permissions The credential lacks the required permission.
429 rate_limited The rate limit was exceeded; retry after the Retry-After period.
503 service_unavailable A dependency is temporarily unavailable (for phishing_resistant, also when the credential data cannot be read); retry after the Retry-After period.

Example

curl -X POST https://api.eu.keenauth.com/v1/organizations/org_01j9xk3m7q8r2s4t6v8w0y2z4a/policies/mfa:preview \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"settings":{"required_for":"all","allowed_factors":["totp","webauthn"]}}'
keenauth organizations policies preview org_01j9xk3m7q8r2s4t6v8w0y2z4a mfa \
  --data '{"settings":{"required_for":"all","allowed_factors":["totp","webauthn"]}}'