Repository navigation
Let library consumers of openshell-core choose the crypto backend #4967
Description
Problem
Since v0.1.5, openshell-core depends on openshell-crypto through the workspace dependency, which sets features = ["aws-lc"]. A crate that uses openshell-core or openshell-sdk as a library therefore always builds the AWS-LC backend, and cannot leave the choice to its own binaries. openshell-crypto already supports this: "with defaults disabled an embedder must install its backend before any crypto operation", and #4843 adds OpenSSL on the same basis.
The aws-lc feature also enables rcgen/aws_lc_rs, rustls/aws_lc_rs and jsonwebtoken/aws_lc_rs. Cargo unifies features, so every other crate in the consumer's build that uses rcgen switches to AWS-LC too. A consumer has no way to keep its existing backend for code that never touches OpenShell.
Impact
NVIDIA/NemoClaw embeds openshell-core and the SDK in short-lived OpenTofu provider processes. OpenTofu starts each provider many times per command. After moving from v0.1.4 to v0.1.5:
- Startup: each provider generates its plugin TLS certificate with
rcgenat startup, and that now goes through AWS-LC. AWS-LC seeds its random generator from CPU jitter entropy (tree DRBG) on first use, which takes 20-35 ms per process on Linux arm64. Provider startup went from about 4 ms to about 24 ms. Key generation and signing take well under 1 ms, and switching P-384 to P-256 made no difference. - Tests: CPU time for a provider contract suite doubled (12.4 s to 23.8 s), and the suites' summed time grew by 50-60% in CI (chore(deps): upgrade OpenShell to v0.1.5 NemoClaw#13786).
A long-running gateway pays the seeding cost once. A process that starts often pays it every time.
Proposal
- Have
openshell-core,openshell-sdkandopenshell-policydepend onopenshell-cryptowith no backend feature. - Select
aws-lcin the binaries (gateway, supervisor, CLI) that need it. - Library consumers then pick a backend and install it, as
openshell-cryptodocuments for embedders.
The gateway and CLI keep AWS-LC as their default; only library consumers gain the choice.
Measurement
A release build of aws-lc-rs 1.18.1 (aws-lc-sys 0.46.0) on Linux arm64:
| Operation | Time |
|---|---|
First aws_lc_rs::rand::fill |
20-35 ms |
aws_lc_rs::init() |
under 0.05 ms |
| P-384 key generation | 0.1-0.3 ms |
| Self-signed certificate | under 0.1 ms |
The compile-time opt-out DISABLE_CPU_JITTER_ENTROPY removes the cost, but it changes the entropy design for the whole process, so NemoClaw isn't using it.
Activity
test: raise contract budgets for OpenShell v0.1.5's aws-lc startup cost
chore(deps): upgrade OpenShell to v0.1.5 (#13786)
test: raise contract test limits for OpenShell v0.1.5's slower provid…
varshaprasad96 commentedon Oct 27, 2026
@cv Looked into this issue, and agree with it - The intent in #3351 was to centralize crypto operations behind a backend-neutral interface while preserving AWS-LC as the default for OpenShell’s executables. We selected aws-lc in the workspace dependency so existing callers would retain their behavior during the migration.
I think that ended up in placing the selection too broadly. Cargo feature unification then propagates it into a consumer’s shared dependencies, including rcgen. Our backend-independence tests covered openshell-crypto directly, so they missed this behavior through openshell-core and the SDK.
I agree that backend selection should move to the executable boundary. I'll fix this in #4843 with removing "aws-lc" from the workspace’s openshell-crypto dependency, retaining default-features = false. Will also add a few more tests to harden
varshaprasad96 commentedon Oct 28, 2026
After checking the scope, I think it would make sense to make separate PR (other than #3351) that addresses this issue, and can later be back ported too. Will open a separate one to address this