You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by "hanahmily (via GitHub)" <gi...@apache.org> on 2026/08/28 13:12:52 UTC
[PR] feat(liaison): scope schema authorization to exact BanyanDB groups [skywalking-banyandb]
hanahmily opened a new pull request, #1317:
URL: https://github.com/apache/skywalking-banyandb/pull/1317
## Why
The previous change gave the liaison a security snapshot, a trusted principal and an
exhaustive method policy table, and used them to authorize the twelve cluster-level methods.
Everything else in the table was classified but left deliberately undecidable: any method
carrying a schema or data permission returned `PermissionDenied` for every caller, the global
administrator included. That was the right way to merge an authorization framework without a
bypass, but it also means an operator who turns RBAC on today cannot manage schema at all.
This change makes the schema half of the API usable, and usable *per group*. A tenant reader
bound to `sw_metric` can read that group's measures, streams, traces, properties, index rules,
index-rule bindings and TopN aggregations, and is refused everything in every other group. A
service account bound to one group can create and evolve the schema it owns without being
granted cluster administration. Group scoping is not deferred: it is what makes a single
BanyanDB cluster safe to share, and it changes the semantics of reads, lists and barrier waits
throughout, so it belongs in the same change as the methods it constrains.
## What it does
Each externally served method is paired with exactly one typed extractor that knows where that
method's request carries its group. Group point reads and deletions carry it as a plain field.
Group creates and updates carry it as `Group.Metadata.Name` — deliberately not as that body's
`Metadata.Group`, so a caller cannot smuggle a write into a group it holds by naming that group
in the wrong field. Registry methods use three structural shapes and no more: the request's own
group for `List`, `Metadata.Group` for point reads and deletions, and the resource body's
`Metadata.Group` for creates and updates. Barrier key waits resolve one scope per key, reading
a `group`-kind key from its name and every other kind from its group.
There is no reflective "find a field called group" rule. BanyanDB request shapes differ far too
much for one, and a rule like that lets a newly added RPC inherit a scope nobody chose. A
coverage test pairs every method with its family instead, so an unclassified or mis-paired
method fails the build rather than quietly picking up a policy.
Two request shapes get special treatment. `Group.List` addresses the whole deployment, so
there is no group to check before the handler runs; it admits any caller holding `schema:read`
somewhere, refuses a caller holding it nowhere, and reduces the response afterwards to the
groups that caller can actually see. The filter is handed the same snapshot the decision was
taken from, so a policy reload landing mid-handler cannot pair one revision's decision with
another revision's visibility. The cluster-wide revision barrier likewise names no group and is
satisfied only by a wildcard `schema:read` grant, since it reports convergence across
everything.
Authorization stays a single decision for both transports. The gRPC interceptor and the
grpc-gateway route bound to the same method go through the same function against the same
table, so there is no second policy to drift and no route that can be reached around. A
request whose group cannot be read from it — absent body, absent metadata, an empty name — is
answered `InvalidArgument` rather than being folded into an authorization outcome, so a caller
that sent something malformed learns that, and learns nothing about what it would otherwise
have been permitted to do.
```mermaid
flowchart TD
H["HTTP :17913<br/>Basic middleware"] -->|verified identity as metadata| GW[grpc-gateway]
GW --> AZ
G["gRPC :17912"] --> AZ
AZ["Authorization interceptor<br/>one decision for both transports"]
AZ --> AUTHN{"credentials<br/>verified?"}
AUTHN -->|no| U401["Unauthenticated / 401"]
AUTHN -->|yes| POL["look up the method's policy"]
POL --> ACT{"executor<br/>activated?"}
ACT -->|"no (data methods)"| D403["PermissionDenied / 403<br/>reason: executor_unavailable"]
ACT -->|yes| EXT["resolve scopes via the method's<br/>typed extractor family"]
EXT -->|unresolvable| I400["InvalidArgument / 400<br/>reason: invalid_request"]
EXT -->|"no group: Group.List"| ANY{"holds schema:read<br/>in any scope?"}
EXT -->|"one or more groups"| ALL{"holds the permission<br/>for every group?"}
ANY -->|no| D403
ALL -->|no| D403
ALL -->|yes| HND
ANY -->|yes| HND["handler"]
HND --> FLT{"response filter<br/>for this policy?"}
FLT -->|"no"| OUT["reply"]
FLT -->|"yes: Group.List"| RED["reduce to visible groups<br/>using the request's own snapshot"]
RED --> OUT
```
Because a decision now precedes every schema handler, a refused create, update or delete cannot
leave anything behind — no metadata write, no deletion task, no tombstone — because the handler
never ran. Group deletion in particular is decided before the dry-run, force and deletion-task
paths are consulted, for every combination of those flags. An unauthorized existence check is
refused rather than answered `false`: `false` would be a fact about a group the caller is not
allowed to see, so authorization is settled before existence is disclosed. Conversely an
authorized request for a group that happens not to exist is allowed through, so the handler
still answers `NotFound` and callers keep the status codes they have always seen.
## Compatibility
A deployment with no auth file, a users-only file, or `rbac.enabled: false` is untouched. Group
scope is never consulted, every schema handler still runs, and `Group.List` returns exactly
what the handler produced — an existing bydbctl or OAP client must not quietly start receiving a
shorter list. Nothing persisted or on the wire changes: every scope is read from protobuf
fields that already exist, so there is no new message, field, on-disk layout or internal
protocol, and a liaison built from this table starts unchanged against an older cluster.
Data methods remain fail-closed, with their bounded `executor_unavailable` reason intact, so
the remaining boundary stays observable from outside rather than resting on a comment. The new
`invalid_request` reason joins the existing closed label set, and the decision counter keeps its
two-valued outcome label and its bounded cardinality: no group name, principal or role name
becomes a metric label as a result of decisions becoming group-scoped.
## Testing
Unit coverage proves the family oracle, extraction across all seven registry families, the
malformed-request table, response filtering including snapshot pinning, and the barrier scope
rules. A standalone suite drives the whole schema lifecycle against a real liaison over
generated gRPC clients and the bound gateway routes, provisioning its fixture as the
administrator and waiting through the protected barrier API rather than sleeping, and re-reading
storage as the administrator so a denied mutation's absence is observed rather than inferred.
The direct standalone deployment case gains a schema stage that repeats the matrix against a
container, including the filtered group list and both barrier scope forms.
Fixes apache/skywalking#14015
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(liaison): scope schema authorization to exact BanyanDB groups [skywalking-banyandb]
Posted by "hanahmily (via GitHub)" <gi...@apache.org>.
hanahmily merged PR #1317:
URL: https://github.com/apache/skywalking-banyandb/pull/1317
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(liaison): scope schema authorization to exact BanyanDB groups [skywalking-banyandb]
Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #1317:
URL: https://github.com/apache/skywalking-banyandb/pull/1317#issuecomment-5453029946
## [Codecov](https://app.codecov.io/gh/apache/skywalking-banyandb/pull/1317?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 50.28%. Comparing base ([`3530dd9`](https://app.codecov.io/gh/apache/skywalking-banyandb/commit/3530dd9b5cefaa4fef60eec91ecbfbdfcaf243c5?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`bdd9e79`](https://app.codecov.io/gh/apache/skywalking-banyandb/commit/bdd9e7935ccf5bc25cc86e220260ff0f82f0f0b9?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
:warning: Report is 410 commits behind head on main.
<details><summary>Additional details and impacted files</summary>
```diff
@@ Coverage Diff @@
## main #1317 +/- ##
==========================================
+ Coverage 45.97% 50.28% +4.30%
==========================================
Files 328 282 -46
Lines 55505 29307 -26198
==========================================
- Hits 25520 14736 -10784
+ Misses 27909 13213 -14696
+ Partials 2076 1358 -718
```
| [Flag](https://app.codecov.io/gh/apache/skywalking-banyandb/pull/1317/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
|---|---|---|
| [fodc](https://app.codecov.io/gh/apache/skywalking-banyandb/pull/1317/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `59.91% <ø> (?)` | |
| [pkg](https://app.codecov.io/gh/apache/skywalking-banyandb/pull/1317/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `47.66% <ø> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.
</details>
[:umbrella: View full report in Codecov by Harness](https://app.codecov.io/gh/apache/skywalking-banyandb/pull/1317?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
<details><summary> :rocket: New features to boost your workflow: </summary>
- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org