A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
atcr.io
docker
container
atproto
go
1package auth
2
3import (
4 "context"
5 "fmt"
6
7 "atcr.io/pkg/atproto"
8)
9
10// HoldAuthorizer checks if a DID has read/write access to a hold
11// Implementations can query local PDS (hold service) or remote XRPC (appview)
12type HoldAuthorizer interface {
13 // CheckReadAccess checks if userDID can read from holdDID
14 // Returns: (allowed bool, error)
15 CheckReadAccess(ctx context.Context, holdDID, userDID string) (bool, error)
16
17 // CheckWriteAccess checks if userDID can write to holdDID
18 // Returns: (allowed bool, error)
19 CheckWriteAccess(ctx context.Context, holdDID, userDID string) (bool, error)
20
21 // GetCaptainRecord retrieves the captain record for a hold
22 // Used to check public flag and allowAllCrew settings
23 GetCaptainRecord(ctx context.Context, holdDID string) (*atproto.CaptainRecord, error)
24
25 // IsCrewMember checks if userDID is a crew member of holdDID
26 IsCrewMember(ctx context.Context, holdDID, userDID string) (bool, error)
27}
28
29// CheckReadAccessWithCaptain implements the standard read authorization logic
30// This is shared across all HoldAuthorizer implementations
31// Read access rules:
32// - Public hold: allow anyone (even anonymous)
33// - Private hold: require authentication (any authenticated user)
34func CheckReadAccessWithCaptain(captain *atproto.CaptainRecord, userDID string) bool {
35 if captain.Public {
36 // Public hold - allow anyone (even anonymous)
37 return true
38 }
39
40 // Private hold - require authentication
41 // Any authenticated user with a DID can read
42 if userDID == "" {
43 // Anonymous user trying to access private hold
44 return false
45 }
46
47 // For MVP: assume DID presence means they have sailor.profile
48 // Future: could query PDS to verify sailor.profile exists
49 return true
50}
51
52// CheckWriteAccessWithCaptain implements the standard write authorization logic
53// This is shared across all HoldAuthorizer implementations
54// Write access rules:
55// - Must be authenticated
56// - Must be hold owner OR crew member
57func CheckWriteAccessWithCaptain(captain *atproto.CaptainRecord, userDID string, isCrew bool) bool {
58 if userDID == "" {
59 // Anonymous writes not allowed
60 return false
61 }
62
63 // Check if DID is the hold owner
64 if userDID == captain.Owner {
65 // Owner always has write access
66 return true
67 }
68
69 // Check if DID is a crew member
70 return isCrew
71}
72
73// ErrHoldNotFound is returned when a hold's captain record cannot be found
74var ErrHoldNotFound = fmt.Errorf("hold not found")
75
76// ErrUnauthorized is returned when access is denied
77var ErrUnauthorized = fmt.Errorf("unauthorized")