Caddy module to require at-proto authentication and restrict routes to DIDs
3

Configure Feed

Select the types of activity you want to include in your feed.

1package caddyatprotoauth 2 3import ( 4 "fmt" 5 "net/http" 6 7 "github.com/caddyserver/caddy/v2" 8 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" 9 "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" 10 "github.com/caddyserver/caddy/v2/modules/caddyhttp" 11) 12 13func init() { 14 caddy.RegisterModule(Gate{}) 15 httpcaddyfile.RegisterHandlerDirective("atproto_gate", parseCaddyfileGate) 16} 17 18// Gate acts as a middleware that guards endpoints 19// and validates the session cookie. 20type Gate struct { 21 Allow []string `json:"allow,omitempty"` 22} 23 24// CaddyModule returns the Caddy module information. 25func (Gate) CaddyModule() caddy.ModuleInfo { 26 return caddy.ModuleInfo{ 27 ID: "http.handlers.atproto_gate", 28 New: func() caddy.Module { return new(Gate) }, 29 } 30} 31 32// Provision sets up the module. 33func (g *Gate) Provision(ctx caddy.Context) error { 34 // Initialize identities and cache resolved handles here. 35 return nil 36} 37 38// Validate checks that the configuration is valid. 39func (g *Gate) Validate() error { 40 if len(g.Allow) == 0 { 41 return fmt.Errorf("atproto_gate requires at least one 'allow' entry") 42 } 43 return nil 44} 45 46// UnmarshalCaddyfile implements caddyfile.Unmarshaler. 47func (g *Gate) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { 48 for d.Next() { 49 for nesting := d.Nesting(); d.NextBlock(nesting); { 50 switch d.Val() { 51 case "allow": 52 g.Allow = append(g.Allow, d.RemainingArgs()...) 53 default: 54 return d.Errf("unrecognized subdirective '%s'", d.Val()) 55 } 56 } 57 } 58 return nil 59} 60 61// parseCaddyfileGate parses the atproto_gate directive from a Caddyfile. 62func parseCaddyfileGate(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { 63 var g Gate 64 err := g.UnmarshalCaddyfile(h.Dispenser) 65 return &g, err 66} 67 68// ServeHTTP implements caddyhttp.MiddlewareHandler. 69func (g *Gate) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { 70 // 1. Verify stateless cookie here 71 // 2. If invalid/missing, initiate redirect to PDS or Auth Hub 72 // 3. If valid, set headers (X-Atproto-Did) and proceed 73 74 // Example: inject header for downstream (to be implemented correctly) 75 // r.Header.Set("X-Atproto-Did", "did:plc:xxx") 76 77 return next.ServeHTTP(w, r) 78}