Integrate go-p11-kit into Pelican and use it to sign TLS connection#2706
Merged
patrickbrophy merged 14 commits intoPelicanPlatform:mainfrom Dec 19, 2025
Merged
Integrate go-p11-kit into Pelican and use it to sign TLS connection#2706patrickbrophy merged 14 commits intoPelicanPlatform:mainfrom
patrickbrophy merged 14 commits intoPelicanPlatform:mainfrom
Conversation
patrickbrophy
requested changes
Oct 3, 2025
Contributor
patrickbrophy
left a comment
There was a problem hiding this comment.
This is just some of the things I caught looking at the code. On a broader view, was the design always supposed to be that the service admin needs to run the commands in another shell?
Contributor
Author
This is a good point - the goal of this PR is "Pelican as a p11 server" so that the consequent XRootD development could be done. The testing recipe above provides a way to validate if Pelican can work as a p11 server. |
patrickbrophy
approved these changes
Oct 28, 2025
Contributor
patrickbrophy
left a comment
There was a problem hiding this comment.
This looks good @h2zh! LGTM
d0e2e83 to
28cee02
Compare
- New pelican/p11proxy with Start/Stop, Info, Options. - Serve a PKCS#11 slot via p11kit.Handler exposing a private key (Go crypto.Signer) and X.509 cert. - Autodetect engine (pkcs11.so) and module (p11-kit-client.so) and write OPENSSL_CONF. - Generate pkcs11: URI and export P11_KIT_SERVER_ADDRESS; never write private keys to disk; cleanup socket/temp on stop.
- Start helper early in origin_serve.go and cache_serve.go; auto-disable with WARN if deps missing.
Consolidate logics Set the default of Server_EnablePKCS11 to false because this is still in the dev process Initialize PKCS#11 helper after the defaults are set up Remove the unused cancel context in CacheServe and OriginServe. Log cleanup errors in p11proxy.Stop(). Log errors from the p11-kit handler goroutine. Harden the socket path to avoid predictable paths. Hand test / unit test pass after this change
XRootD launchers and tests can now discover helper state without re-instantiating it, and the socket handling is safe against stale files. - Maintain the helper’s last-known Info under a RWMutex, expose it via CurrentInfo - Ensure the socket directory exists, pick a unique socket name, and clear stale sockets before binding, avoiding conflicts when multiple modules start, or when an old file is still lying around
- Plumb PKCS#11 helper-derived env vars (P11_KIT_SERVER_ADDRESS, OPENSSL_CONF), and stop injecting a client key file into XRootD when the helper is active
- Right before we render the XRootD template, `ConfigXrootd` now rewrites `xrdConfig.Server.{TLSCertificateChain, TLSKey}` fields
-- When PKCS#11 is off, both fields are set to the same runtime file (which still contains cert+key), so the template produces the same path it used to.
-- When PKCS#11 is on, Server.TLSCertificateChain stays pointed at the runtime cert file (no key), while Server.TLSKey is swapped out for the pkcs11 URI (pkcs11:...). That URI needs to reach XRootD so it can use the engine to sign with the helper.
-- Note: the template sees whatever is in the `XrootdConfig` struct at render time, not the raw config parameter.
- Unit test: assert the runtime file only contains cert material when pkcs11 signing is active
- expose the detected p11-kit client module path via p11proxy.Info, simplify error capture in Proxy.Stop - harden socket setup/IDs/logging in the RPC server - propagate PKCS11_MODULE_PATH plus more detailed trace logging to both the unprivileged launcher and the privileged linux launcher - preserve the parent environment
- Configure Federation.DiscoveryUrl by using the new helper function `test_utils.MockFederationRoot(t, nil, nil)` introduced by PR PelicanPlatform#2747 - Use federation's discovery URL as token issuer for Director/Federation tests
- Since the Proxy handles its own cleanup internally via the context, there's no need for the caller to pass in an errgroup to manage cleanup goroutines - Made the entire Stop() method idempotent by adding a stopped flag and mutex, so multiple calls to Stop() won't cause issues - Made socket file removal idempotent by checking if the error is "file not exists" before logging a warnin - Added special handling for EOF errors in the p11proxy handler. During shutdown, when connections are closed, EOF errors are expected and should not be logged as warnings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Update: Rewrote this PR description so it now walks through how Pelican and XRootD work together to deliver full PKCS#11-based TLS signing end to end.
This PR wires XRootD’s OpenSSL TLS layer into Pelican’s PKCS#11 helper so the TLS private key never has to be read by the xrootd process. Instead, every TLS signature goes through a PKCS#11 URI backed by go-p11-kit.
Highlights
Server_EnablePKCS11is set tofalsebecause this feature is under development. But when this feature is enabled in prod, I plan to switch the default totrueto enforce this security enhancement.Technical details
How to test
Rebuild XRootD with this counterpart PR in pelicanplatform/xrood repo: PelicanPlatform/xrootd#42
Install necessary libraries to connect XRootD to Pelican's p11proxy
(TODO: Once all reviewers approve this PR, I @h2zh need to contact BrianA & Mat to bundle these new libraries into the Pelican image build & other build workflows (KOJI/OSG/...)
Modify config parameter in
pelican.yamlto enable the built-in p11 proxy in Pelican.Make the TLS key unreadable to the xrootd user. Example:
Spin up Pelican Registry, Director, Origin/Cache. Run Origin/Cache with verbose p11-kit logging (e.g.
P11_KIT_DEBUG=rpc pelican origin serve -p 8447)If this PR works, you can see lines as below in the Origin logs. It means pkcs11 is supplying the key and xrootd no longer need read access to the PEM TLS key file.