fix(spaces)!: simplespace independent read/write access and authority interop #113
Labels
No labels
breaking-change
bug
documentation
duplicate
enhancement
good first issue
help wanted
performance
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/ATProto.NET#113
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of the v0.7.0 update cycle. Upstream changed
com.atproto.simplespaceto separate read access from write access (bluesky-social/atproto#5496, merged 2026-09-10; proposal PR #105). The spaces-alpha PDS image, the hosted alpha PDS and the reference app (bulletin) all run the new API. Against them the SDK is now wire-incompatible on both the client and the server side:createSpace→ 400.getSpacethrowsJsonException, because therequiredPolicyfield is missing.updateSpace(policy:)returns 200 and silently changes nothing.addMemberno longer exists.Comparing against the current reference also surfaced interop bugs that were already present in v0.6.0 (pre-existing below).
com.atproto.space.*, LtHash, the commit/MAC, the CAR format, the tokens, DPoP and thespace:scope grammar are all unchanged upstream.Client (
ATProtoNet)createSpace/updateSpace/getSpace: replacepolicywithreadPolicyandwritePolicy. On create both are required on the wire; the client defaults each toMemberListPolicyand always sends both. On update each is optional and replaces the old value wholesale.addMember. AddputMember(space, did, read, write), an upsert that replaces both flags, plus theSpaceUrioverload.listMembersentries gainread/write.checkUserAccessgains a requiredaccess(read|write);clientIdis omitted for write checks.Server (
ATProtoNet.Server)SimpleSpaceRecord,ISimpleSpaceStore, the in-memory and EF stores, and the EF entities: splitPolicyintoReadPolicyandWritePolicy. ReplaceAddMemberAsync/IsMemberAsyncwithPutMemberAsync(space, did, read, write)/GetMemberAsyncreturning the flags. Document the migration: copyPolicyinto both columns and give existing membersread=write=true, matching upstream's003-space-accessmigration.putMember(owner only) replacesaddMember; create/update/get carry both policies.SimpleSpaceAccessPolicyevaluatesreadPolicy+appAccessfor credentials, andwritePolicywith no app perimeter for writes. The authority is always admitted.notifyWriteon write access and answer 403 when the writer is refused. Pre-existing: no user perimeter is applied today, while upstream already had one at our baseline.notifyWrites to endpoints registered withregisterNotify(best-effort, off the request path). Pre-existing:SpaceWriteNotifier.NotifyWriteAsynchas no caller.?did=, but the lexicon parameter isuser(SimpleSpaceAccessPolicy.cs:221), so everyManagingAppPolicyspace refuses everyone. Senduserandaccess, and omitclientIdfor writes.#atproto_space_hostonly, with no fallback to#atproto_pds(SpaceAuthority.cs:87-98). Notifications to authorities on ordinary PDSes are logged and dropped, so their writer set never fills. Resolve with the fallback and sendaud= the bare authority DID (what the reference authority checks).checkUserAccess→did:web:…#bulletin, registered notify recipients) must use the full service identifier asaud, not the bare DID.notifyWriteon an SDK authority configured withServiceDidrejects notifications from reference PDSes, which sendaud= the authority DID. Accept{authority, authority#atproto_space_host, ServiceDid}.notifyWrite.revmust be a valid TID; reject it asInvalidRequestbefore auth.Docs, sample, tests
docs/testing-spaces.md: the alpha artifacts exist (ghcr.io/bluesky-social/atproto:pds-spaces-alpha,@atproto/pds@alpha, the invite-onlyspaces-alpha.host.bsky.network). Pin the image digest or source commit. The "no image" claim is also in CHANGELOG 0.6.0 and should be corrected in[Unreleased], not rewritten in history.docs/spaces.md: read/write policies,putMember, and writer-set semantics (writers admitted bywritePolicy, and an authority may exclude writers).SpacesSampleand the integration tests (SpaceNetworkFixture,SimpleSpacePolicyTests). Add a test thatputMember(read: true, write: false)gets a credential but stays out of the writer set.Before merging
Re-check the open upstream issues #5487 (
type→spaceType), #5491 (arepoparam onregisterNotify) and #5462 (an unauthenticated policy variant). Adopt any that have landed.CHANGELOG:
Breaking changes, with migration notes (policy:→readPolicy:/writePolicy:,AddMemberAsync→PutMemberAsync,ISimpleSpaceStore/SimpleSpaceRecordshape changes, EF column split). The pre-existing items go underFixed.