Skip to content

ACL authorization

-acl-file points to a JSON file. The file maps client identities to the lock names that they can acquire. The flag requires -tls-client-ca. The identity comes from the verified mutual TLS (mTLS) certificate. Without mTLS, there is no identity to authorize. Without an access-control list (ACL) file, authorization is off, and each client can acquire each lock.

{
"rules": [
{ "identity": "spiffe://prod/worker/*", "locks": ["nightly/*", "shard-?"] },
{ "identity": "admin.svc.cluster.local", "locks": ["*"] }
]
}

Deny by default, union of matches: a rule is applicable if its identity pattern matches the client. The server permits a lock if a locks pattern of one applicable rule matches the lock name. The sequence of the rules has no meaning. There are no priorities, no overrides, and no deny rules. Thus the meaning of each ACL file is immediately clear.

“Allow everything” is an explicit "*", not an absent rule. A rule must have an identity pattern and a minimum of one locks pattern. A rule that can never permit a lock is a configuration error, and the server must reject it.

With the file above:

Client identity Lock Result
spiffe://prod/worker/7 nightly/import allowed — the first rule matches
spiffe://prod/worker/7 shard-3 allowed — ? matches one character
spiffe://prod/worker/7 shard-31 denied — ? matches exactly one character
admin.svc.cluster.local anything allowed — explicit *
spiffe://staging/worker/1 nightly/import denied — no identity pattern matches

The two sides of a rule are glob patterns:

  • * matches any substring, including /
  • ? matches exactly one character
  • each other character is a literal

A pattern matches the full string, not a part of it. Strings are raw UTF-8. They are case sensitive, and the server does not normalize them. The ?match= filter of the admin API uses the same glob language. Thus a pattern from a rule gives the same result in a query.

SIGHUP reads the file again. A reload can fail because of an unreadable file, invalid JSON, or a bad rule. Then the server keeps the previous rules and writes the error to the log. See the SIGHUP contract.

The server answers a refused ACQUIRE with ERROR code 0x18 (“not authorized for lock”) and closes the connection. This is a client error code: the same bytes fail in the same way again. Thus a correct client shows the error and stops, and does not retry.

Denials are visible in three locations:

  • the monolock_acl_denials_total counter (metrics)
  • a log line at info level
  • a denied event in the audit log, with the identity and the lock name