~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
146 lines · 6.3 KB Raw History

Scope Validation Comparison: pds.js vs atproto PDS

Comparison of OAuth scope validation between this implementation and the official AT Protocol PDS.


Scope Types Supported

Scope TypeFormatpds.jsatproto PDS
atprotoStaticFull accessRequired for all OAuth
transition:genericStaticFull accessFull repo/blob bypass
transition:emailStaticN/ARead account email
transition:chat.bskyStaticN/AChat RPC access
repo:<collection>?action=<action>GranularFull parsing + enforcementFull parsing + enforcement
blob:<mime>GranularFull parsing + enforcementFull parsing + enforcement
rpc:<aud>:<lxm>GranularNot implementedFull parsing + enforcement

Scope Enforcement by Endpoint

com.atproto.repo.createRecord

Aspectpds.jsatproto PDS
Scope checkScopePermissions.allowsRepo(collection, 'create')permissions.assertRepo({ action: 'create', collection })
Required scoperepo:<collection>?action=create or transition:generic or atprotorepo:<collection>?action=create or transition:generic or atproto
OAuth-only checkYes (legacy tokens without scope bypass)Yes (legacy Bearer bypasses)
Error response403 "Missing required scope "repo:...?action=...""403 "Missing required scope "repo:...?action=...""

com.atproto.repo.putRecord

Aspectpds.jsatproto PDS
Scope checkallowsRepo(collection, 'create') AND allowsRepo(collection, 'update')assertRepo({ action: 'create' }) AND assertRepo({ action: 'update' })
Required scoperepo:<collection>?action=create&action=updaterepo:<collection>?action=create&action=update
NotesRequires both since putRecord can create or updateRequires both since putRecord can create or update

com.atproto.repo.deleteRecord

Aspectpds.jsatproto PDS
Scope checkScopePermissions.allowsRepo(collection, 'delete')permissions.assertRepo({ action: 'delete', collection })
Required scoperepo:<collection>?action=deleterepo:<collection>?action=delete

com.atproto.repo.applyWrites

Aspectpds.jsatproto PDS
Scope checkIterates all writes, checks each unique action/collection pairIterates all writes, asserts each unique action/collection pair
Required scopeAll repo:<collection>?action=<action> for each writeAll repo:<collection>?action=<action> for each write
Per-write validationYesYes

com.atproto.repo.uploadBlob

Aspectpds.jsatproto PDS
Scope checkScopePermissions.allowsBlob(contentType)permissions.assertBlob({ mime: encoding })
Required scopeblob:<mime-type> (e.g., blob:image/*)blob:<mime-type> (e.g., blob:image/*)
MIME type awarenessYes (validates against Content-Type)Yes (validates against Content-Type)

app.bsky.actor.getPreferences

Aspectpds.jsatproto PDS
Scope checkRequires auth onlypermissions.assertRpc({ aud, lxm })
Required scopeAny valid authrpc:app.bsky.actor.getPreferences

app.bsky.actor.putPreferences

Aspectpds.jsatproto PDS
Scope checkRequires auth onlypermissions.assertRpc({ aud, lxm })
Required scopeAny valid authrpc:app.bsky.actor.putPreferences

Scope Parsing

Featurepds.jsatproto PDS
Scope string splittingscope.split(' ')ScopesSet class
Repo scope parsingparseRepoScope()RepoPermission.fromString()
Repo scope formatrepo:collection?action=create&action=updaterepo:collection?action=create&action=update
Blob scope parsingparseBlobScope()BlobPermission.fromString()
RPC scope parsingNoneRpcPermission.fromString()
Scope validationReturns null for invalidValidates syntax, ignores invalid
Action deduplicationYes (via Set)Yes
Default actionsAll (create, update, delete) when no ?action=All (create, update, delete) when no ?action=

Permission Checking

Featurepds.jsatproto PDS
Permission classScopePermissionsScopePermissions / ScopePermissionsTransition
allowsRepo(collection, action)YesYes
allowsBlob(mime)Yes (with MIME wildcard matching)Yes (with MIME wildcard matching)
allowsRpc(aud, lxm)N/AYes
Transition scope handlingtransition:generic bypasses repo/blob checkstransition:generic bypasses repo/blob checks
Error messagesSpecific missing scope in errorSpecific missing scope in error

OAuth Flow

Featurepds.jsatproto PDS
scopes_supported in metadata['atproto']['atproto'] (but accepts granular)
Scope validation at PARNoneValidates syntax
Scope stored in tokenYesYes
Scope returned in token responseYesYes
atproto scope requiredChecked at endpointsRequired at token verification

Transition Scope Behavior

Scopepds.jsatproto PDS
transition:genericBypasses all repo/blob permission checksBypasses ALL repo/blob permission checks
transition:chat.bskyNot implementedAllows chat.bsky.* RPC methods
transition:emailNot implementedAllows account:email:read

Summary

Categorypds.jsatproto PDS
Scope parsingFull parser for repo/blobFull parser per scope type
Enforcement granularityPer-collection, per-actionPer-collection, per-action
Transition scope supporttransition:generic onlyFull
MIME-aware blob scopesYesYes
RPC scopesNoYes
Error specificityNames missing scopeNames missing scope

Remaining Gaps

  1. RPC scopes — rpc:<aud>:<lxm> parsing and enforcement not implemented
  2. Additional transition scopes — transition:chat.bsky and transition:email not implemented
  3. Scope validation at PAR — Could validate scope syntax during authorization request