@@ -13,6 +13,8 @@ The plugins in the repository include:
1313 in the core XRootD (with the addition of making in-progress files not-visible in the namespace).
1414- ` XrdN2NPrefix ` : A Name2Name (N2N) plugin that performs path prefix substitution,
1515 allowing logical paths to be mapped to different physical paths on disk.
16+ - ` XrdAccHttpCallout ` : An authorization plugin that makes HTTP callouts to an external service
17+ to determine access permissions.
1618
1719
1820## Building and Installing
@@ -354,6 +356,159 @@ forward, while `pfn2lfn` (physical to logical) applies them in reverse.
354356** Note** : When used with ` oss.localroot ` , the N2N plugin automatically prepends the localroot
355357to physical paths returned by ` lfn2pfn() ` .
356358
359+ ### Configure the AccHttpCallout Authorization Plugin
360+
361+ The AccHttpCallout plugin provides HTTP-based authorization callouts to an external service.
362+ This allows for flexible, centralized authorization logic implemented in any language that
363+ can serve HTTP requests.
364+
365+ To load the plugin, use the ` acc.authlib ` directive:
366+
367+ ```
368+ acc.authlib libXrdAccHttpCallout.so
369+ ```
370+
371+ (an absolute path may be given if ` libXrdAccHttpCallout-5.so ` does not reside in a system directory)
372+
373+ There are several configuration directives for the AccHttpCallout module:
374+
375+ ```
376+ acchttpcallout.endpoint <url>
377+ acchttpcallout.cache_ttl_positive <seconds>
378+ acchttpcallout.cache_ttl_negative <seconds>
379+ acchttpcallout.passthrough [true|false]
380+ acchttpcallout.trace [all|error|warning|info|debug|none]
381+ ```
382+
383+ - ` acchttpcallout.endpoint ` : ** (Required)** The HTTP(S) endpoint URL that will be called for
384+ authorization decisions. The plugin will make HTTP GET requests to this endpoint with query
385+ parameters for the path and operation (verb).
386+
387+ Example:
388+ ```
389+ acchttpcallout.endpoint https://auth.example.com/authorize
390+ ```
391+
392+ - ` acchttpcallout.cache_ttl_positive ` : Cache time-to-live in seconds for positive (authorized)
393+ responses. Default is 60 seconds. This reduces load on the authorization service by caching
394+ successful authorization decisions.
395+
396+ Example:
397+ ```
398+ acchttpcallout.cache_ttl_positive 120
399+ ```
400+
401+ - ` acchttpcallout.cache_ttl_negative ` : Cache time-to-live in seconds for negative (denied)
402+ responses. Default is 30 seconds. This prevents repeated unauthorized requests from
403+ overwhelming the authorization service.
404+
405+ Example:
406+ ```
407+ acchttpcallout.cache_ttl_negative 60
408+ ```
409+
410+ - ` acchttpcallout.passthrough ` : Controls behavior when authorization fails. If ` true ` , the
411+ plugin will pass the request to the next configured authorization plugin (if any). If ` false `
412+ (default), authorization failures result in immediate denial.
413+
414+ Example:
415+ ```
416+ acchttpcallout.passthrough false
417+ ```
418+
419+ - ` acchttpcallout.trace ` : Controls logging verbosity. Can be specified multiple times (values
420+ are additive) and multiple values can be given per line.
421+
422+ Example:
423+ ```
424+ acchttpcallout.trace info
425+ ```
426+
427+ #### HTTP Callout Protocol
428+
429+ When a client attempts to access a resource, the plugin makes an HTTP GET request to the
430+ configured endpoint with the following query parameters:
431+
432+ - ` path ` : The URL-encoded path being accessed (e.g., ` /store/data/file.txt ` )
433+ - ` verb ` : The HTTP/WebDAV verb corresponding to the operation (e.g., ` GET ` , ` PUT ` , ` DELETE ` )
434+
435+ The bearer token from the client is passed in the ` Authorization ` header:
436+
437+ ```
438+ Authorization: Bearer <token>
439+ ```
440+
441+ The authorization service should respond with:
442+
443+ - ** 200 OK** : Access is granted
444+ - ** 401 Unauthorized** or ** 403 Forbidden** : Access is denied
445+ - ** 5xx Server Error** : Error executing authorization (treated as failure)
446+
447+ #### Response Format
448+
449+ The response body may optionally contain JSON data with additional information:
450+
451+ ``` json
452+ {
453+ "authorizations" : [
454+ {
455+ "verb" : " GET" ,
456+ "prefixes" : [" /store/data" , " /store/mc" ]
457+ }
458+ ],
459+ "user" : " jdoe" ,
460+ "group" : " physicists"
461+ }
462+ ```
463+
464+ - ` authorizations ` : An array of additional path prefixes that are authorized for the token.
465+ These are cached to avoid redundant callouts for related paths.
466+ - ` verb ` : The HTTP/WebDAV verb (e.g., ` GET ` , ` PUT ` )
467+ - ` prefixes ` : Array of path prefixes authorized for this verb
468+
469+ - ` user ` : Username to add to the security context (optional)
470+ - ` group ` : Group name to add to the security context (optional)
471+
472+ #### Operation to Verb Mapping
473+
474+ The plugin maps XRootD operations to HTTP/WebDAV verbs as follows:
475+
476+ | XRootD Operation | HTTP/WebDAV Verb |
477+ | -----------------| ------------------|
478+ | Read | GET |
479+ | Readdir | PROPFIND |
480+ | Stat | HEAD |
481+ | Update/Create | PUT |
482+ | Delete | DELETE |
483+ | Mkdir | MKCOL |
484+ | Rename/Insert | MOVE |
485+
486+ #### Complete Example Configuration
487+
488+ ```
489+ # Enable the HTTP protocol
490+ xrd.protocol http:1094 libXrdHttp.so
491+
492+ # Load the authorization plugin
493+ acc.authlib libXrdAccHttpCallout.so
494+
495+ # Configure the authorization endpoint
496+ acchttpcallout.endpoint https://pelican-auth.example.com/api/v1/authorize
497+
498+ # Configure caching (2 minutes for positive, 1 minute for negative)
499+ acchttpcallout.cache_ttl_positive 120
500+ acchttpcallout.cache_ttl_negative 60
501+
502+ # Don't pass through to other auth plugins on failure
503+ acchttpcallout.passthrough false
504+
505+ # Enable info-level logging
506+ acchttpcallout.trace info
507+
508+ # Export paths
509+ all.export /store
510+ ```
511+
357512## Startup and Testing
358513
359514Assuming you named the config file ` xrootd-http.cfg ` , as a non-rootly user run:
0 commit comments