Obexal Docs

Docs/Access control/Simulation and versions

Policy versioning and simulation

Every access policy change becomes an immutable version you can restore, and any candidate policy can be simulated against 30 days of real sign-in traffic before you apply it.

Changing a conditional access policy is one of the riskiest admin operations: a wrong rule can lock a whole workforce out. Obexal removes the guesswork twice over: every change is archived as an immutable version you can restore, and any candidate policy can be simulated against your real sign-in traffic before you apply it.

Every change is a version

Each successful application of the access policy (a PUT or a restore) appends a version to an append-only history. A version records the full snapshot of rules and default action, a version number, a note describing the change, the author's email and an RFC 3339 timestamp. History is never rewritten: restoring an old version creates a new one on top, with a note like "Restauration de la version 3". Archiving is best-effort by design: a storage incident on the history never blocks applying the policy itself.

Browse and restore

curl -sS https://accounts.obexal.com/v1/admin/access-policy/versions \
  -H "Authorization: Bearer $OBEXAL_API_TOKEN"
{
  "versions": [
    {
      "id": "9f0e6c2a", "version": 4,
      "rules": [{"name": "Office", "networks": ["203.0.113.0/24"], "action": "allow", "enabled": true}],
      "defaultAction": "deny",
      "note": "Modification",
      "author": "admin@example.com",
      "createdAt": "2026-06-28T09:14:03Z"
    }
  ]
}

The list returns the 50 most recent versions, newest first. To roll back:

curl -sS -X POST \
  https://accounts.obexal.com/v1/admin/access-policy/versions/9f0e6c2a/restore \
  -H "Authorization: Bearer $OBEXAL_API_TOKEN"
# 204 No Content: the snapshot is re-applied as a NEW version

A restore goes through the same validation and the same anti-lockout guard as any change: a version that would deny your current connection today, or require an MFA you have not enrolled, is refused. Both endpoints require the tenant:manage permission; a custom domain replaces accounts.obexal.com.

Simulate before you apply

POST /v1/admin/access-policy/simulate takes exactly the same body as the PUT and applies nothing. It evaluates both the current policy and the candidate against the real sign-in IPs of your tenant over the last 30 days (up to 1000 distinct IPs, each weighted by how many sign-ins it produced), resolving countries with the same local GeoIP database as at login. The answer is counterfactual: what would have changed for the traffic you actually had.

Example

curl -sS -X POST https://accounts.obexal.com/v1/admin/access-policy/simulate \
  -H "Authorization: Bearer $OBEXAL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      {"name": "Office", "networks": ["203.0.113.0/24"], "action": "allow", "enabled": true}
    ],
    "defaultAction": "require_mfa"
  }'
{
  "windowDays": 30,
  "distinctIps": 42,
  "sampled": 1287,
  "unparseable": 0,
  "current": {"allow": 1287},
  "candidate": {"allow": 1121, "require_mfa": 166},
  "changes": [
    {
      "from": "allow", "to": "require_mfa",
      "count": 166, "distinctIps": 9,
      "sampleIps": ["198.51.100.23", "192.0.2.41"]
    }
  ]
}

Reading the results

  • current and candidate give the distribution of actions, weighted by sign-in occurrences: here 166 of the 1287 recent sign-ins would switch to an MFA step-up.
  • changes is the from/to matrix, sorted by impact: each entry carries the weighted count, the number of distinct IPs affected and up to 5 sample IPs to investigate.
  • An empty changes array means the candidate policy changes nothing for your real traffic.

The workflow to adopt: simulate, check that nobody lands in deny unexpectedly, apply, and keep the version history as your rollback path.

Limits

  • The sample is the sign-in IPs recorded over the last 30 days, capped at 1000 distinct IPs; a brand-new tenant with no history gets empty distributions.
  • Time-window rules are evaluated at the instant of the simulation, not at each sign-in's original timestamp: a business-hours rule shows its effect for "now".
  • IPs that cannot be parsed are counted in unparseable and excluded from the distributions.
  • Simulation covers the rule-based access policy, not the risk score, which depends on each user's history at sign-in time.