nirum-lang/nirum

Adopt capability-based security into Nirum services

dahlia opened this issue · 0 comments

I suggest Nirum to adopt capability-based security into its services. To begin with, read the article of the topic on Wikipedia:

Capabilities achieve their objective of improving system security by being used in place of forgeable references. A forgeable reference (for example, a path name) identifies an object, but does not specify which access rights are appropriate for that object and the user program which holds that reference. Consequently, any attempt to access the referenced object must be validated by the operating system, based on the ambient authority of the requesting program, typically via the use of an access control list (ACL). Instead, in a system with capabilities, the mere fact that a user program possesses that capability entitles it to use the referenced object in accordance with the rights that are specified by that capability. In theory, a system with capabilities removes the need for any access control list or similar mechanism by giving all entities all and only the capabilities they will actually need.

Long story short, whereas ACL-based security controls operations on objects/resources, capability-based security controls references to objects/resources. Think of S3-like file storage for example. ACL-based security controls operations like list-dir, read-file, etc, e.g.:

type path = text;

@error
union file-error = not-found | forbidden;

service storage-service (
    [path] list-root () throws file-error,
    [path] list-dir (path directory-path) throws file-error,
    binary read-file (path file-path) throws file-error,
);

Instead, capability-based security controls what references are accessible e.g.:

@error
union dir-error = not-a-dir;

@error
union file-error = not-a-file;

service root (
    # List all accessible files/dirs.
    [file] list-dir(),
);

service file (
    # List all accessible files/dirs.
    [file] list-dir () throws dir-error,
    # Get contents of the file.
    binary read-file () throws file-error,
);

Note that service methods return references to other services. This is key concept of capabilities: if a service gives you a reference to another service it means you're granted to access that. The minimum permission is just a reference to the public endpoint to the root service.

In order to adopt this new concept of security, we of course need to implement several things Nirum currently doesn't have:

  • Service methods need to be possible to return other services.
    • Also they may need to take other services? (I'm not sure though.)
    • Or generally we might treat references to services as first-citizen like other types (i.e. record, union, etc).
  • Under the hood, references to services should be signed to be ensured they are granted, legal, and not forged.
    • Of course method calls on a service (which is securely refereed) also need to be signed.

Opinions or any ideas?