---
title: "Verify effective access"
description: "Check that every source ACL is still allowed through RBAC, and read the EFFECTIVE_OK, EFFECTIVE_MISSING and EFFECTIVE_UNKNOWN results."
url: https://monedula.dev/flock/docs/acl-rbac-converter/how-to/verify-effective-access/
---
After `apply`, `verify` asks MDS, for every source ACL, whether the original principal, operation and resource is now allowed, so it also catches a binding that exists but grants nothing, for example when a principal does not resolve or the cluster ID is wrong. It changes nothing, and it is the gate before any ACL is deleted.

## Before you start

- An applied plan whose [run directory](/flock/docs/acl-rbac-converter/reference/cli/#the-run-directory) still holds the `acls.json` it was made from, which the default mode reads.
- The same MDS flags as for [`apply`](/flock/docs/acl-rbac-converter/how-to/apply-to-mds/).

## Steps

### 1. Run verify

```bash
monedula-acl-rbac verify \
  --plan runs/2026-05-21T10-00-00Z/plan.json \
  --mds-url https://mds.example.com \
  --mds-token-file ~/.confluent/token
```

`verify` checks that `plan.json` still matches its checksum, then writes `verify.json` to the path you give with `--out`, otherwise into its run directory: `--run-dir` when you give it, otherwise the directory of `--plan`. It stamps the plan's SHA-256 into `verify.json`, so the delete commands can tell which plan it checked. `--verify-parallelism` sets the number of concurrent MDS lookups, 8 by default.

### 2. Read the results

The default mode, `--mode effective`, classifies each source ACL:

- `EFFECTIVE_OK`: the binding grants the access the ACL granted.
- `EFFECTIVE_MISSING`: the binding exists in MDS, but the principal still cannot perform the operation. Common causes are a principal that does not resolve in MDS, such as a TLS distinguished name passed through unmapped or an LDAP setup that did not resolve it, group membership that has not propagated yet, and a scope mismatch, such as a wrong cluster ID in `scopes.yaml` ([Find the cluster IDs for scopes.yaml](/flock/docs/acl-rbac-converter/how-to/find-cluster-ids/)).
- `EFFECTIVE_UNKNOWN`: MDS did not answer clearly, for example because it lacks the lookup endpoint. The tool treats this as unsafe.

To list every result that is not `EFFECTIVE_OK`:

```bash
jq '.results[] | select(.status != "EFFECTIVE_OK")' verify.json
```

`--format json` prints the same envelope on stdout as `verify.json` holds on disk, described by [verify-summary.v1.json](/flock/docs/acl-rbac-converter/reference/formats/verify-summary-v1/).

### 3. Fix missing access and run verify again

Fix the cause of each `EFFECTIVE_MISSING` result, for example with a principal mapping in `principals.yaml`, then run `verify` again. Right after `apply`, MDS's role-binding cache can lag a few seconds behind, so run `verify` again before you look for another cause.

If the fix changes the plan, for example a corrected cluster ID or principal mapping, plan again, apply the new plan and verify it: a `verify.json` belongs to the plan it checked.

### 4. Accept unknown results only where MDS cannot answer

Where MDS lacks the effective-access lookup endpoint, add `--accept-unknown-verify` to treat `EFFECTIVE_UNKNOWN` results as `EFFECTIVE_OK`:

```bash
monedula-acl-rbac verify \
  --plan runs/2026-05-21T10-00-00Z/plan.json \
  --mds-url https://mds.example.com \
  --mds-token-file ~/.confluent/token \
  --accept-unknown-verify
```

The downgrade is recorded in the `detail` field of each result it changed, so it stays visible in `verify.json`. It never affects `EFFECTIVE_MISSING`.

## Check only that the bindings exist

`--mode bindings-exist` only confirms that the binding rows exist in MDS, with no group or LDAP lookups. It writes `verify.json` too, replacing the effective results unless you pass `--out` with another path, and `delete-acls` accepts its `BINDING_EXISTS` results. To keep both, write each mode to its own file, as the live-mds-migration example does with `--out out/verify-bindings.json` and `--out out/verify-effective.json`, and pass the effective one to `delete-acls`.

## Check it worked

`verify` exits 0 when every result is OK, and 5 when any result is `EFFECTIVE_MISSING`, `EFFECTIVE_UNKNOWN` or, in bindings-exist mode, a missing binding, so it works as a CI gate. `verify.json` is written before that check, so you can still read it after a non-zero exit. The `verify` line of `monedula-acl-rbac status runs/2026-05-21T10-00-00Z` counts the results, for example `0 missing, 0 unknown`.

Then wait at least 24 hours before you [delete the converted ACLs](/flock/docs/acl-rbac-converter/how-to/delete-converted-acls/).

## Related

- [Recover from a failed run](/flock/docs/acl-rbac-converter/how-to/recover-from-a-failed-run/) covers what to do when verify keeps failing.
- The [verify command reference](/flock/docs/acl-rbac-converter/reference/cli/verify/) lists every flag and exit code.
- Runnable version: [live-mds-migration](https://github.com/monedula-dev/monedula-acl-rbac-converter/tree/main/examples/live-mds-migration), which runs both verify modes against a real MDS.