Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@brghena
Copy link
Contributor

@brghena brghena commented Dec 1, 2025

Pull Request Overview

This pull request documents a revised IPC system for Tock. Rendered here

The document mostly speaks for itself, but the summary is that it proposes replacing the existing IPC design with a new ecosystem of IPC capsules. It proposes some initial designs for these capsules and documents the thinking behind them. This is a joint work of the Network working group informed by discussions over the last few months.

This is still a draft PR. You might notice several TBDs. Primarily, we've left a shared memory mechanism unspecified for now. We do have some designs for this, but we wanted to request community comments and work on implementations of the existing mechanisms before moving on to the more complicated shared memory work.

This is in the RFC folder for now, but we could move it later if there is an alternative location people prefer, maybe a TRD.

Testing Strategy

Documentation

TODO or Help Wanted

This pull request still needs: comments and thoughts from the community. Let us know if you spot any potential problems or if you have an application with tradeoffs we haven't considered.

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • [N/A] Ran make prepush.

@brghena brghena added rfc Issue designed for discussion and to solicit feedback. WG-Network In the purview of the Network working group. labels Dec 1, 2025
@github-actions github-actions bot added documentation and removed WG-Network In the purview of the Network working group. labels Dec 1, 2025
@brghena brghena added the WG-Network In the purview of the Network working group. label Dec 1, 2025
Copy link
Contributor

@jrvanwhy jrvanwhy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppose you are writing a Tock application that needs to store encryption keys in a secure location. You know that the IPC service for storing keys is named "keystore" and that the real implementation (the one you trust) has application ID 0123456789. Your app generates an encryption key, and wants to send it to that application.

How does it know it is sending the encryption key to app ID 0123456789 and not an imposter that also uses the "keystore" name? Is preventing that impersonation the IPC Name Registry capsule's responsibility?

Upon discovery, it provides opaque process IDs which can be used to refer to
processes in other IPC mechanisms.

If validation of services or clients is desired, this capsule could perform
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "validation" mean here? Client authentication and/or authorization, or something else (like verifying the client process implements particular APIs)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means authentication / authorization. I should clarify that in the text.

**Commands**:
* Existence
* Register as service with allowed string name
* Discover service with allowed string name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are races between service registration and service discovery handled (i.e. what happens if a process tries to discover service X when the process that provides service X is still starting up and hasn't registered yet)? Is that an implementation detail that is outside the scope of this document?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should document that in this document. Since servers can choose to register themselves, it is possible to search the registry and not discover a server yet. That would result in "no match". The application should try again at a later time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"a later time" is kinda vague. Maybe we should have a "new service registered" upcall that prompts processes to re-try service discovery?

Servers do not need to be aware of clients in advance, as they will receive a
process ID with each request. Clients do need to have previously discovered a
process ID for the server, possibly via the IPC Name Registry or possibly via a
separate mechanism (for example, they could be hard-coded).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So presumably something in the kernel has to store the list of discovered process IDs for each process, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The kernel doesn't need to track discovered Process IDs. Instead, processes can hang on to them in process memory.

For clients, they can query the "Registry" to match some name to a Process ID, and then store that ID locally for use. For servers, they get a Process ID attached to incoming messages, and can store that if they want to use it later.

The kernel would have to hang on to discovered Process IDs if we wanted to do real client authentication. See the "Process Descriptor Tables" section:

### Process Descriptor Tables

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this means "clients are supposed to discover the process ID first before passing messages to it", not "the kernel needs to reject messages if the client did not discover the process ID first".

@brghena
Copy link
Contributor Author

brghena commented Dec 7, 2025

Suppose you are writing a Tock application that needs to store encryption keys in a secure location. You know that the IPC service for storing keys is named "keystore" and that the real implementation (the one you trust) has application ID 0123456789. Your app generates an encryption key, and wants to send it to that application.

How does it know it is sending the encryption key to app ID 0123456789 and not an imposter that also uses the "keystore" name? Is preventing that impersonation the IPC Name Registry capsule's responsibility?

In the proposed initial implementation plan, there is no mechanism to ensure that the "keystore" service is not an imposter. However, application credentials is already is a thing in Tock. So you could ensure that only credentialed applications are running, and therefore that no imposter can exist.

If we did authentication in the Registry, we could verify at registration-time that the "keystore" process is authentic and authorized to use that identifier. The IPC Name Registry would be responsible for this. How exactly it would do it is a little unclear. Probably something to do with TBF headers and credentials.

Our thinking is that doing this authentication at registration-time should be possible (i.e., the design should allow it to be added in the future if someone wants to), but also that it isn't very important because platforms that really care would also use credentialed applications and verify them.

@jrvanwhy
Copy link
Contributor

jrvanwhy commented Dec 8, 2025

platforms that really care would also use credentialed applications and verify them.

I think you're asserting that all Tock deployments that care about preventing impersonation would have a form of secure boot (only allowing certain apps to run and denying apps the kernel has never heard of). At the time application IDs were designed, we had a use case for which that assertion was false (that is, we wanted to be able to run unknown applications and provide security to those applications). I'm not sure those uses cases exist for Tock anymore, and they're certainly difficult to support (in particular w.r.t. anti-starvation guarantees), but if we're going to rule them out we should do so thoughtfully rather than accidentally.

I do agree that it could be retrofit, though. I think you could allow processes to self-service their security by providing one or both of the following commands:

  1. A command to verify that a particular process ID corresponds to a particular application ID.
  2. A command to retrieve the application ID for a particular process ID.

(Because application IDs are variable-length, having both commands would be helpful). Retrofitting anti-impersonation would make IPC insecure-by-default, however.

@jrvanwhy
Copy link
Contributor

jrvanwhy commented Dec 8, 2025

I do agree that it could be retrofit, though. I think you could allow processes to self-service their security by providing one or both of the following commands:

1. A command to verify that a particular process ID corresponds to a particular application ID.
2. A command to retrieve the application ID for a particular process ID.

I forgot that you cannot have multiple running processes with the same application ID, so the first command could just be "get the process ID for a particular application ID".

@jrvanwhy
Copy link
Contributor

jrvanwhy commented Dec 9, 2025

Let me try to step back and give a high-level view of what we're trying to achieve with IPC authentication, and the available options for doing so.

Why does IPC need to use application IDs?

First, why do we need authentication? The threat model's Isolation Provided to Processes section says:

Confidentiality: A process' data may not be accessed by other processes or by capsules, unless explicitly permitted by the process. [...]

So if a process tries to send data using the IPC system, the IPC capsule is not allowed to send that data just anywhere. The process must have a way to control where that data goes. So how does a process specify what that data can be shared? The What is an "Application"? section has the answer:

What is an "Application"?

Formally, a Tock application is the set of all processes that have a particular application ID (as detailed in the AppID TRD).

Every process has an application ID (which may be global or locally unique), so every process is part of an application.

Application IDs are generally used as a way to grant access to something. For example, a process that wants to send a message to another process will generally do so by sending the message to that process' application ID. Doing so grants that application access to the message. The IPC system is responsible for identifying which process has that application ID (if any) and giving the message to that process.

So when a process gives the IPC capsule a message to send, it should have control over the application ID of the process(es) that receives that message.

Client authentication versus server authentication

Conceptually, the threat model's statement applies to both client->server and server->client messages. But to make it more concrete, lets look at examples where each type of authentication matters.

Client->server authentication example

Suppose that application C is a cryptography server, which can perform encryption for other Tock apps on the system. App A has some data it wants to encrypt, that it does not want to share with the world. App A wants to send that data to application C, and know that it is not sending that data to any other application.

Server->client authentication example

Suppose application F implements a filesystem. Application A has already stored data in that filesystem, and has set the data's permissions such that no other app can read that data. App B contacts the filesystem and asks for app A's data. The filesystem application F needs to be able to determine that app B is not app A and deny that request.

Application ID history

Unfortunately, with this PR we find ourselves reinventing parts of the app ID infrastructure. Lets look at the history of application ID design in Tock to inform the current design.

First application ID proposal

The first design proposal for application IDs was on 2025-06-05 on the tock-dev list. This proposal introduced application identifiers as a variable-length byte string, which would be used for authentication and authorization by various Tock features (syscall filtering, ipc, secure boot, cryptography, storage, etc).

It did not include any form of short ID (note that I'm not capitalizing short ID, because this is NOT the same meaning of short ID as the AppID TRD).

Introduction of short IDs

Application ID proposal v2 was the first proposal to introduce short IDs. In v2, short IDs are subsystem-specific identifiers -- that is, the storage system and syscall filter would have distinct short ID spaces.

The reason for this discrepancy was incompatible persistence between the systems:

  1. The storage system needs to track the association between a short ID and an application ID for as long as that application has data in storage. If an app is uninstalled but it leaves files behind, its short ID remains alive. This effectively requires the storage short ID to be stored in flash memory.
  2. The syscall filter shouldn't need to depend on storage (syscall filtering can still be used on a system with no filesystem). It also needs to have short IDs for applications that are in the syscall filter ACL that are not -- and never have been -- installed on that particular Tock system.

I did not design short IDs for IPC in that proposal (this is clarified later in the thread).

Application ID TRD: shared Short IDs.

The application ID TRD mashed the two distinct short ID systems from proposal v2 into a single Short ID shared between subsystems. With this design:

  1. If a board has a filesystem but not a syscall filter, the filesystem generates short IDs for all processes.
  2. If a board has both a filesystem and a syscall filter, the syscall ID assignment needs to depend on both so that its IDs live as long as either the application is in the syscall filter ACLs or the application is referenced by on-disk structures.
  3. If a board has a syscall filter but not a filesystem, then the syscall filter generates short IDs. If the syscall filter encounters an application ID that is not in its ACLs, it assigns it a "locally unique" ID that compares unequal to everything. Such a process effectively cannot interact with any Tock subsystem that uses short IDs.

Options for IPC

IPC has several options for security identifying applications.

Use the full application ID

Application IDs are unique among running processes, so the IPC system could exclusively use full application IDs (this is the design from proposal v2).

This has a couple drawbacks. First, application IDs are large and variable-size, which makes it difficult to allocate memory to store them.

The other drawback is that having less-persistent IDs is actually a benefit for IPC, as is already highlighted in this PR:

Nothing in particular should be required to use ProcessIDs for IPC, in fact they were designed with IPC in mind. That they are not identical across process restarts is a boon, as clients will almost certainly need to restart communication if a server restarts.

Use the Short ID

This solves the "large and variable-size" problem, but keeps the persistence drawback.

It also introduces a new drawback: processes with a locally-unique Short ID would be unable to use IPC at all, though this is not really a new drawback because it was an intentional compromise in the application ID TRD (there's no succinct description here, it's a PR discussion so large I cannot get GitHub to load all of it).

Use process IDs as a custom short ID.

This uses process IDs as a short ID (note lowercase -- this is the v2 proposal's concept of short ID) for IPC. The IPC system (presumably the name registry capsule) would need to provide an API that allows processes to discover the relationship between process IDs and application IDs. Then the rest of the IPC system can use only process IDs. This is what I suggested a few hours ago.

One minor drawback here: if you expose a "get process ID for application ID" command, then that command leaks information about whether a given application is running on the system. That's probably fine to leak, but there are a few ways to avoid it if needed (could be more specific about when a process ID is returned, or only offer a "get application ID for process ID" command).

Something else?

Maybe if the main use for IPC is networking then maybe it could use UDP/TCP/etc port numbers as short IDs. IDK, I'm just spitballing to make the point that we have other options here.

Network WG notes response

Now that we've paged in the application ID discussion history, I'll go through and respond to the discussion from the 2025-12-08 network WG meeting.

  • Branden: For this first part, there are at least two mechanisms for discovery we've thought of. I thought of using string names provided by the application code at runtime. These have to be fixed-length to be stored in Grants. Upside is that application can pick whatever and it's clear in the source. Alternative Leon mentioned was using Package Names in the TBF header. This is what the old IPC used. It's nice because application can't just change it, but I'm worried that it's a bit hidden in the build system which makes it hard to figure out.
  • Alex: I'd go for the TBF header so an app can't lie.
  • Branden: That can lie though. At compile time someone could set that to anything.
  • Leon: But you can verify it and with app-signing you can know that apps come from a signed place. Technically the name and the app code are both signed. But the header is MUCH easier to verify. Harder to check that the name that's allowed matches a promise.

The entity (individual/organization/etc) that signs a cryptographically-signed app is not necessarily the same organization that controls what apps run on a Tock system.

Consider a Tock app store where developers can push signed application binaries. A developer should be able to set up their own PKI (Public Key Infrastructure), sign their own app (let's call it A), and know that no-one else can impersonate their app (assuming the Tock system is correctly implemented). That should be true even if that app is deployed alongside a malicious app (let's call it M).

Application IDs would prevent app M from impersonating app A. However, app M could contain the same service name in its header as app A. So headers alone are not trustworthy enough.

  • Branden: Yes and no. Registration is asynchronous explicitly because we don't know what the registration mechanism might be, and we want to allow for a system that checks signatures and says "no". But for now I was thinking about not having any of that implemented. Given that we have app-signing in Tock already, it's not clear to me that IPC should be double-checking stuff.
  • Leon: Yeah, IPC shouldn't

IPC shouldn't implement its own cryptographic credential checking, but it does need to hook into the existing application ID infrastructure to satisfy use cases with mutually-distrustful apps. I don't think that needs to be mandatory for all IPC users, though -- we can make "verify this process has the expected application ID" a separate step that security-conscious applications must perform. I don't like that it is insecure by default, but it might be the best tradeoff for Tock overall.

  • Leon: Using something like ShortID probably requires a multi-step identification process. I'd guess that you have to do one lookup for the ShortID and another query for whether there's a valid signature behind it. I'm not convinced it's the same interface. Maybe a good first step is to try to compile as many scenarios as we can think of. Check with stakeholders about what they need. We could then look for whether there should/can be one shared interface.
  • Leon: Even if it isn't shared, there should be one clear resulting identifier that can be used in other IPC mechanisms.
  • Tyler: The only reason I'm pushing back on the multi-capsule design is that it feels like it could be brittle, with differing errors for instance. 15.4 has this problem where we're maintaining multiple interfaces. It would be good to have a generalized interface.
  • Branden: Proposal is two registry mechanisms. That should make it easy for someone to make a third version eventually. And it would let us look at the two and see where commonalities lie.

You should be able to trust that a Short ID is valid, it's just that if it's locally unique you can't do much with it (e.g. a client that sends a message to a server cannot receive a response, because the server has no way to send the message back).

A Short ID <-> application ID mapping capsule should already exist as an application ID mechanism (it doesn't, but it should). So if you're doing a multi-step lookup, IPC would only need to know the process ID <-> Short ID lookup step.

But because not every process has a Short ID, I think it makes sense for IPC to have a single process ID <-> application ID registry and skip Short IDs entirely. That would make IPC simpler and more capable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation rfc Issue designed for discussion and to solicit feedback. WG-Network In the purview of the Network working group.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants