diff --git a/reference/users-and-roles/overview.md b/reference/users-and-roles/overview.md index bdfdd0a7..bf73a0b2 100644 --- a/reference/users-and-roles/overview.md +++ b/reference/users-and-roles/overview.md @@ -79,6 +79,40 @@ The `operations` field in a permission object restricts which Operations API cal Operations normally restricted to `super_user` can be selectively granted by including them in the list. If `operations` is not set, the role can call any non-`super_user` operation, subject to table CRUD permissions. + + +An operation the list omits is denied whatever else the role carries — the list is checked ahead of every other permission on the role. Earlier v5 releases let table DDL and SQL around it; both now go through it. + +So grant by listing, and build a role up rather than trying to narrow `super_user` — `add_role` and `alter_role` reject `super_user` or `cluster_user` set to `true` alongside any other key. A role that maintains one database's tables and queries them with SQL: + +```json +{ + "operation": "add_role", + "role": "orders_maintainer", + "permission": { + "operations": ["sql", "create_table", "drop_table"], + "structure_user": ["orders_db"], + "orders_db": { + "tables": { + "orders": { + "read": true, + "insert": true, + "update": false, + "delete": false, + "attribute_permissions": [] + } + } + } + } +} +``` + +`sql` has to be listed or the role cannot run SQL at all. Listing it grants the interface, not the data: the statement is still checked against the table permissions above, so this role can `SELECT` and `INSERT` on `orders` and nothing else. That check is what separates the `read_only` and `standard_user` groups below, which both include `sql`. + +`create_table` and `drop_table` have to be listed too, and `structure_user` then limits them to `orders_db`. `create_database` and `drop_database` additionally require `structure_user: true`. + +The value must be an array of strings; a non-array value is rejected on write. A role that already holds one — a pre-5.0 role that granted a database named `operations`, before the key became reserved — can stop the instance loading its user cache ([harper#2194](https://github.com/HarperFast/harper/issues/2194)). + **Permission Groups** Groups expand to a predefined set of operations and can be mixed with individual operation names: diff --git a/release-notes/v5-lincoln/5.3.md b/release-notes/v5-lincoln/5.3.md index 1dc7e574..627ad222 100644 --- a/release-notes/v5-lincoln/5.3.md +++ b/release-notes/v5-lincoln/5.3.md @@ -32,6 +32,17 @@ See [Configuration Options](/reference/v5/configuration/options#node). Harper now defers rejection of an unrecognized Basic or Bearer credential on the application HTTP port until a handler claims the request. Harper-owned routes still return the normal unauthorized response. Unowned routes can fall through to application middleware with the original `Authorization` header unchanged. This lets catch-all applications and reverse proxies apply their own authentication schemes without URL exemptions or header rewriting, and the unauthorized response such an application returns — including its own `WWW-Authenticate` challenge — is passed back to the client unchanged. Internal authentication failures continue to fail closed. See [Authentication and route ownership](/reference/v5/security/overview#authentication-and-route-ownership). +### Operation Allowlist Enforcement + +A role's `permission.operations` allowlist is now checked before every other privilege check on the role, so an operation the list omits is denied whatever else the role carries. Table DDL and SQL previously went around it. + +**A role that relied on either will lose access on upgrade.** Two cases to audit, both fixed by adding the operation to the list: + +- `operations` combined with `structure_user` — `create_table`, `create_attribute`, `drop_table`, and `drop_attribute` now have to be listed. `structure_user` still scopes them to its databases. +- `operations` omitting `sql` — the role can no longer run SQL. + +Roles with no `operations` field are unaffected, as are roles that already list everything they call. See [Operation Permissions](/reference/v5/users-and-roles/overview#operation-permissions). + ### OIDC Trusted Publishing A CI runner can now authenticate to Harper with no stored credential. It presents an identity token minted by its own provider, and if that token verifies against a trust policy configured on the instance, Harper returns a one-hour operation token for the user the policy names — the same exchange npm, PyPI, and AWS STS `AssumeRoleWithWebIdentity` use. This replaces a 30-day refresh-token secret with a rule you configure once and revoke with `drop_oidc_trust`.