Secretspec 0.20

We’ve released secretspec 0.20, which includes 5 new providers, git and Docker credential helpers.

Most importantly we’re working towards releasing resolver IPC that Nix will be able to use without introducing new dependencies, which was the main review objection to existing PR.

We’ve also split out secrets handling refactoring in Nix (PR).

Disclaimer: LLMs have been used

7 Likes

Thank you for the update, I was curious about the IPC proposal and I stumbled on IPC architecture | SecretSpec and I’m genuinely surprised by the claims or the needs of SecretSpec here.

Version 1 requires private stdio sessions on Linux, macOS, and Windows plus a pure-C client. zlink is Rust-only and its ready-made transport is Unix-domain sockets. Passing anonymous sockets is a transport-specific zlink extension, not standard Varlink, and Windows would need a separate handle-transfer design.

Varlink has C bindings (referenced from varlink.org): GitHub - varlink/libvarlink: C implementation of the Varlink protocol and command line tool · GitHub and passing anonymous socket is as transport specific as JSON-RPC no? Windows supports AF_UNIX (since Windows 10, recent builds), but, I mean whatever transport you’ll use for JSON-RPC is going to be useful for Windows as well. So I’m really confused about the portability claim when compared to JSON-RPC 2.0 ^^

Missing lifecycle semantics. SecretSpec would still have to define version and capability negotiation, deadlines, cancellation, message bounds, leases, shutdown, and the trust model.

It seems like to me this is also true of JSON-RPC 2.0, no? That’s the problem with these “very simple” protocol, they are not as nice as Cap’n’Proto or gRPC when it comes to that, albeit even those won’t go and say what is the trust model or specify your cap negotiation algorithm.

No net simplification. Named sockets require authentication, permissions, discovery, and stale-socket cleanup. Connection pools replace the current request-ID table with another security-sensitive state machine.

I genuinely don’t get this argument, why this property of named sockets are problematic? Varlink has a Linux registry in /run and varlinkctl handle discoverability for you. The UNIX permission model (or file descriptor passing) handle permissions and authentication, systemd handle stale-socket cleanup.

What does JSON-RPC 2.0 does here that makes it nicer?

No multiplexing. Varlink pipelines calls in order but has no request IDs. One blocked call delays later replies and cannot be cancelled independently. A pool of connections avoids this, but adds channel scheduling, descriptor limits, and replacement after cancellation.

Why does that matter for something like SecretSpec? Like, I suspect that something like SecretSpec handles interactive prompts or permission prompts, so you open 1 connection for each of those and cancellation is well just dropping that connection (that was blocked) no? Is there a reason to have a mono-connection where you can send many requests with request IDs there? I get that JSON-RPC 2.0 has an ID here. Arguably, if you are going to operate over a UDS thing, you can do the exact same thing as JSON-RPC 2.0 and add your own correlation ID and have the server side ack any request and process them async and offer a Stream function (that’s a classical technique that many Varlink servers use to achieve this).

So, really, I’m just curious if you can spare more technical details of the specific needs of SecretSpec, reading the wire protocol did not help me to figure out what is really special about JSON-RPC that you cannot do with Varlink. Thank you in advance!

5 Likes

Seems like varlink is popular in Nix circles! :slight_smile:

That’s a bit of sloppy explanation, but Windows doesn’t support socketpair() that makes it avoid filesystem, which makes is secure.

The Rust claim is about that libvarlink lags behind features, I forgot exactly what it was when I was doing analysis.

Yeah, that’s why the argument why not just JSON+RPC instead of another abstraction.

I don’t want filesystem involvement with the IPC. If we’re making things trying to fix security, there should be no permissions involved, only child/parent processes.

There might be secretspec provider/resolver implementations that handle a lot of traffic so we don’t want a serial channel. I consider performance important, something like 1Password takes 1s just to fetch a secret and these things add up (remember nix-daemon). I was consider having one channel per connection, but then you’re starting to deal with multiplexing, which makes this harder to implement than it should be.

Overall I’m not that much against varlink and arguments aren’t that strong, I’m just not sure relying on another upstream that doesn’t seem to 100% fit will long term be good for IPC. It’s one less OSS project I need to contribute to. We’re going to support many SDKs and I just don’t want to be able to contribute something upstream and make my ways to get it merged into specific coding style. That’s a huge drain of energy from our side.

There’s also something nice to have all the freedom to design the spec we want and let agent implement it for any language from scratch against a strong test suite.

It’s more like the alternative standard to D-Bus in the Linux desktop than any personal preference. :slight_smile:

I still don’t get it. stdin & stdout can be used with Varlink, no? Is that what you want?

I see but then this is not an argument for JSON+RPC more than it is for Varlink, I guess?

It sounds a bit of a shame for something that wants to advertise secret management on the desktop as well but it’s up to you to do what you want with this project. I don’t think fixing security means moving everything to child/parent anonymous file descriptors passing, not everything can be this way ^^

But you can have that performance with Varlink, even in presence of blocking 1P APIs that takes 1s to fetch a secret. I don’t get why you need multiplexing if you open one channel per connection, but OK. I just wanted to understand if I was missing something.

Your replies helped me a lot to understand your “Why not Varlink?”, I understand not wanting to participate in an upcoming standard of Linux desktop IPC because the value out of controlling everything seems more important to you if I understand it well. I feel like indeed that you could have chosen Varlink over JSON-RPC but I guess the most important thing is that you don’t have to deal with Varlink libraries implementers neither people who are involved in Varlink development if you have a need and can freely own your IPC implementation garden. That seems fair.

Thank you for the replies and good luck with secretspec!

1 Like

Once Varlink matures I’m happy to add support for it.

We’re moving fast at the moment so it would only slow us down.