feat: authorize what a subscription may listen to - #35
Merged
Conversation
Dev sessions collide on the same ports, and DevSpace treats a failed bind as fatal — the session dies, nothing syncs, and the pod silently keeps running whatever it started with. A dev session replaces a pod; it has no business binding host ports.
Subscribe checked two of its room kinds. Everything else -- every organization's, agent's and workload's event stream, and any string at all -- was readable by any authenticated caller: the Gateway confirms an identity exists and forwards the room list untouched. architecture/authz.md already states the table. Identity-keyed rooms are settled by equality; the rest are gated on the caller's relation to the organization that owns the entity, which for workload and agent rooms means asking their owning service which organization that is. The config and chart have carried RUNNERS_ADDR and AGENTS_ADDR all along with nothing reading them. Three rooms cannot be checked yet and say so where they are handled: volume and trace, because no response carries the organization, and egress_rules, which is one global literal rather than the per-org room the document describes. Anything else is refused rather than inheriting an accidental allow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Subscribechecked two of its room kinds. Everything else — every organization's, agent's and workload's event stream, and any arbitrary string — was readable by any authenticated caller. The Gateway only confirms an identity exists and forwards the room list untouched.architecture/authz.md#notifications-servicealready states the table, and this implements it:thread_participant:/instance_inbox:/sandbox_owner:organization:membersandbox_org:can_list_sandboxesworkload:memberon the workload's organizationagent:memberon the agent's organizationworkload:andagent:are keyed by entity id, so the owning service is asked which organization that is. BothGetWorkloadandGetAgentalready accept an identity-less internal caller.notifications' config and chart have carriedRUNNERS_ADDRandAGENTS_ADDRall along with nothing reading them.Missing rooms (
sandbox_owner:,sandbox_org:,volume:) are now classified rather than falling through to the unknown bucket, and anything genuinely unrecognised is refused.Three exceptions, each named where it is handled rather than left silent:
volume:andtrace:— both specified as "member on the owning organization", but neither owner will say which one that is.GetTracereturns raw OTLP spans, and neither the agents nor the runnersVolumemessage carries anorganization_id. Closing them needs that field.egress_rules— the Egress Gateway and the Egress service both use this bare literal, not the per-org room the document describes. There is no organization to check against, and default-denying it would cut off rule invalidation.A failed lookup denies rather than allows: a subscription outlives the request that opened it.