Conversation
5d10243 to
aa33c72
Compare
| - all | ||
| oauth_scope: conversations_name | ||
| oauth_scope: conversations_name # deprecated, will be ignored if 'oauth_scopes' is present. | ||
| oauth_scopes: ["write-only:conversations_name"] |
There was a problem hiding this comment.
Note for the reviewer: there is no ReadConversationName constructor, so we shouldn't list it here or we'll get a unit test failure when matching nginz.conv and swagger.json.
| BatchType (BatchLogged, BatchUnLogged), | ||
| Blob (Blob), | ||
| ColumnType (AsciiColumn, BigIntColumn, BlobColumn, BooleanColumn, DoubleColumn, IntColumn, ListColumn, MaybeColumn, TextColumn, TimestampColumn, UdtColumn, UuidColumn, VarCharColumn), | ||
| ColumnType (AsciiColumn, BigIntColumn, BlobColumn, BooleanColumn, DoubleColumn, IntColumn, ListColumn, MaybeColumn, SetColumn, TextColumn, TimestampColumn, UdtColumn, UuidColumn, VarCharColumn), |
There was a problem hiding this comment.
Note for the reviewer: cassandra still contains old tokens, so we return a set of tokens instead of one string, translating new tokens into lists containing themselves only, and old tokens into lists with all the implications.
| ngx_str_t oauth_scope; | ||
| ngx_flag_t zauth; // 1=on, 0=off | ||
| ngx_str_t oauth_scope; // scope base, tier implied by the method (deprecated) | ||
| ngx_str_t oauth_scopes; // whole scopes, separated by spaces; supersedes oauth_scope |
There was a problem hiding this comment.
Note to self: give this file another read.
| import Servant hiding (Handler, JSON, Tagged, addHeader, respond) | ||
| import Servant.OpenApi.Internal.Orphans () | ||
| import Test.QuickCheck (Arbitrary (..)) | ||
| import Test.QuickCheck (Arbitrary (..), listOf1) |
There was a problem hiding this comment.
Note to self: give this file another read.
| instance IsOAuthScope 'ReadFeatureConfigs where | ||
| toOAuthScope = ReadFeatureConfigs | ||
| instance IsOAuthScope 'ReadConversationsCode where | ||
| toOAuthScope = ReadConversationsCode |
There was a problem hiding this comment.
Note to self: I think here the order got garbled. Fix!
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved backward-compatibility issues affect legacy scope parsing, refresh-token permissions, empty scopes, and directive validation.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
This PR introduces independent OAuth read, write-only, and delete-only scopes while retaining legacy configuration support.
Changes:
- Adds
oauth_scopessupport across nginx, libzauth, OAuth APIs, and charts. - Updates persistence, route documentation, tests, and deployment configurations.
- Documents migration from the deprecated
oauth_scopedirective.
| File | Summary |
|---|---|
services/nginz/third_party/nginx-zauth-module/zauth_module.c |
Adds nginx scope-list handling. |
services/nginz/integration-test/conf/nginz/nginx.conf |
Tests new scope configuration. |
services/brig/test/integration/API/OAuth.hs |
Updates OAuth integration tests. |
services/brig/src/Brig/API/OAuth.hs |
Persists typed scope sets. |
libs/wire-api/test/unit/Test/Wire/API/Routes/OAuthScopes.hs |
Validates route scope declarations. |
libs/wire-api/test/unit/Test/Wire/API/OAuth.hs |
Tests scope parsing and migration. |
libs/wire-api/src/Wire/API/Routes/Public/Galley/Meetings.hs |
Updates meeting route scopes. |
libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs |
Updates conversation route scopes. |
libs/wire-api/src/Wire/API/Routes/Public.hs |
Updates scope documentation rendering. |
libs/wire-api/src/Wire/API/OAuth.hs |
Defines scopes and legacy conversion. |
libs/libzauth/libzauth/src/oauth.rs |
Implements tier-aware verification. |
libs/libzauth/libzauth/src/lib.rs |
Exports verification support. |
libs/libzauth/libzauth-c/src/zauth.h |
Declares the C API. |
libs/libzauth/libzauth-c/src/lib.rs |
Exposes the C wrapper. |
libs/cassandra-util/src/Cassandra/CQL.hs |
Exports Cassandra set support. |
libs/cassandra-util/src/Cassandra.hs |
Re-exports Cassandra support. |
integration/test/Testlib/HTTP.hs |
Adds Host-aware request support. |
integration/test/Test/OAuth.hs |
Adds OAuth integration coverage. |
integration/test/API/Nginz.hs |
Adds nginx OAuth helpers. |
docs/src/developer/reference/config-options.md |
Documents scope configuration. |
deploy/dockerephemeral/federation-v2/nginz/conf/nginx.conf |
Migrates nginx configuration. |
deploy/dockerephemeral/federation-v1/nginz/conf/nginx.conf |
Migrates nginx configuration. |
deploy/dockerephemeral/federation-v0/nginz/conf/nginx.conf |
Migrates nginx configuration. |
charts/nginz/values.yaml |
Defines new route scopes. |
charts/nginz/templates/conf/_nginx.conf.tpl |
Renders new scope directives. |
changelog.d/1-api-changes/WPB-28193-disentangle-oauth-scopes-_write-access-should-not-imply-read-access_ |
Adds API changelog entry. |
changelog.d/0-release-notes/WPB-28193-nginx-conf-syntax-changed |
Documents configuration migration. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| - path: /meetings/([^/]*)/([^/]*)$ | ||
| envs: | ||
| - all | ||
| oauth_scopes: [] # https://wearezeta.atlassian.net/browse/WPB-28194: this will be `["write-only:meetings", "delete-only:meetings"]` soon. |
There was a problem hiding this comment.
Note for the reviewer: https://wearezeta.atlassian.net/browse/WPB-28194 is now just changing this line. If you agree we don't need a separate PR please thumbs-up this, and I'll make another commit.
battermann
left a comment
There was a problem hiding this comment.
Can you verify if the docs: https://docs.wire.com/latest/developer/reference/oauth.html are still up to date with this?
There was a problem hiding this comment.
Ideally we would move these tests to the integration package. But not sure how practical that is and I also don't want this to block the PR.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Critical OAuth compatibility regressions and a test compilation error remain unresolved.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 6
Open (6)
OAuth DELETE scope compatibility is broken · New OAuth DELETE requests reject existing admin tokens · New Read/write scopes omit required DELETE authorization · New Read/write scopes omit required DELETE authorization · New T.splitOnce does not compile · New Integration DELETE route lacks compatible scope · New
Resolved since last review (1)
| - all | ||
| oauth_scope: conversations_code | ||
| oauth_scope: conversations_code # deprecated, will be ignored if 'oauth_scopes' is present. | ||
| oauth_scopes: ["read:conversations_code", "write-only:conversations_code"] |
| location ~* ^(/v[0-9]+)?/conversations/([^/]*)/code { | ||
| include common_response_with_zauth.conf; | ||
| oauth_scope conversations_code; | ||
| oauth_scopes read:conversations_code write-only:conversations_code; |
| location ~* ^(/v[0-9]+)?/conversations/([^/]*)/code { | ||
| include common_response_with_zauth.conf; | ||
| oauth_scope conversations_code; | ||
| oauth_scopes read:conversations_code write-only:conversations_code; |
| location ~* ^(/v[0-9]+)?/conversations/([^/]*)/code { | ||
| include common_response_with_zauth.conf; | ||
| oauth_scope conversations_code; | ||
| oauth_scopes read:conversations_code write-only:conversations_code; |
| # 'testOAuthScopeTiersAreSeparate' and | ||
| # 'testOAuthNewScopesOnDeprecatedAttribute' in | ||
| # integration/test/Test/OAuth.hs. | ||
| oauth_scopes read:conversations_code write-only:conversations_code; |
3a83dbe to
6f238cc
Compare
https://github.com/wireapp/wire-docs/pull/131/changes it's on my list... |
The change to the values.yaml schema is fully backwards compatible, but since the new behavior should ignore `oauth_scope` if `oauth_scopes` is present, this will make wire-api tests fail. good.
Now values.yaml must match docs according to new oauth scope semantics. The actual policy control happens in libzauth and is changed in the next commit.
Until now, it succeeded with a scope-less, and thus useless, token issued, setting the user up for a disappointment.
This morally reverts 2bca04e "Refactor: split up `data OAuthScope` into base and tier."
6f238cc to
848afbd
Compare


https://wearezeta.atlassian.net/browse/WPB-28193
The problem
We need to express the following oauth access policy: we want to grant oauth access to
{PUT,DELETE} /meetings/<domain>/<id>, but not toGETon the same route.The current implementation of oauth scopes is cumulative:
write:conversationsimpliesread:conversations,admin:blaimplieswrite:bla,read:bla. This language cannot express the above policy.Here is what works: we want to grant
write:conversations, so we issuewrite:conversationstokens and addoauth_scope: conversationto the nginz route, and onPUT,POSTrequests, thewrite:is attached to it before checking against the token. We don't want to grantread:conversations, though, but that's ok, because there is no routeGET /conversations, and nginz will never construct one.Now we want to grant
write-onlyanddelete-onlyto/meetings/<id>, which does have aGETroute, so this trick does not work any more.Existing oauth apps and tokens must keep working without interruption.
The solution
Deprecate the
oauth_scopenginx directive and introduce a newoauth_scopesdirective that supports tiersread,write-only,delete-onlyinstead ofread,write,admin.Checklist
changelog.d