diff --git a/README.md b/README.md index b6b5a6e..8e65be3 100644 --- a/README.md +++ b/README.md @@ -5,5 +5,5 @@ When returning an Interface it may be required to append a dummy valueto work ar ```diff - whoami @4 () -> ( you :Api.User ); -+ whoami @4 () -> ( you :Api.User, dummy :UInt8 = 0 ); ++ whoami @4 () -> ( you :Api.User, dummy :UInt8 = 0 ); ``` diff --git a/cache.capnp b/cache.capnp index b249046..16df070 100644 --- a/cache.capnp +++ b/cache.capnp @@ -1,5 +1,8 @@ @0xf6520578f143b471; +using CSharp = import "programming_language/csharp.capnp"; +$CSharp.namespace("FabAccessAPI.Schema"); + using import "utils.capnp".UUID; struct Cache(Value) { diff --git a/claim.capnp b/claim.capnp index a218d27..b5e5148 100644 --- a/claim.capnp +++ b/claim.capnp @@ -3,9 +3,10 @@ using CSharp = import "programming_language/csharp.capnp"; $CSharp.namespace("FabAccessAPI.Schema"); -using import "/capnp/rpc.capnp".SturdyRef; +# TODO: removed SturdyRef to build API in C# +# using import "/capnp/rpc.capnp".SturdyRef; +# using import "persistent.capnp".Persistent; -using import "persistent.capnp".Persistent; using import "resource.capnp".Resource; using import "notify.capnp".Notifiable; using import "utils.capnp".Fallible; @@ -23,7 +24,9 @@ interface Claimable { } interface Lockable { - restore @0 ( sturdy :SturdyRef ) -> ( lock :Lock ); + restore @0 ( ) -> ( lock :Lock ); + # TODO: removed SturdyRef to build API in C# + # restore @0 ( sturdy :SturdyRef ) -> ( lock :Lock ); # Restore a previously saved SturdyRef pointing to a Lock lock @1 () -> ( lock :Lock ); @@ -40,7 +43,7 @@ interface Lockable { } interface Claim extends (Notifiable) { - resource @0 () -> ( resource :Resource ); + resource @0 () -> ( resource :Resource, dummy :UInt8 = 0 ); # Pointer back to the resource this claim comes from. Primarily useful when restoring persisted # claims or restoring after a connection failure. diff --git a/main.capnp b/main.capnp index 9ed96e8..8729e6f 100644 --- a/main.capnp +++ b/main.capnp @@ -21,27 +21,38 @@ struct Version interface Bootstrap { getAPIVersion @0 () -> Version; + # Returns the API version implemented by the server. As a client, you can compare this version with the local currentVersion. getServerRelease @1 () -> ( name :Text, release :Text ); # Returns the server implementation name and version/build number Designed only for human-facing # debugging output so should be informative over machine-readable. # Example: ("bffhd", "0.3.1-f397e1e [rustc 1.57.0 (f1edd0429 2021-11-29)]") - mechanisms @2 () -> ( mechs :List(Mechanism) ); + getServerInfo @2 () -> ( spacename :Text, instanceurl :Text ); + # Returns information about the server, which can be used to resolve MDNS to DNS and display the server name to the user. + + + mechanisms @3 () -> ( mechs :List(Mechanism) ); # Get a list of Mechanisms this server allows in this context. - createSession @3 ( mechanism :Text ) -> ( authentication :Authentication ); + createSession @4 ( mechanism :Text ) -> ( authentication :Authentication ); # Create a new session with the server that you wish to authenticate using `mechanism`. If the # mechanism is a client-first mechanism you can then immediately call Authentication::step with # initial data in a pipelined fashion. If the mechanism is server-first you must call # Authentication::step with a NULL `data` parameter. + + # register @5 () -> (); + # Placeholder for a future capability for users to register themselves. + } struct Session { # An API session with the server. The below capabilities are set to NULL if the authenticated # user doesn't have permission to access the system in question, or if the server does not # implement it. + whoami @0 :User; + # Returns the currently authenticated user. resources @1 :Resources; # Access to the resources configured. diff --git a/persistent.capnp b/persistent.capnp index fefd188..69c3d38 100644 --- a/persistent.capnp +++ b/persistent.capnp @@ -1,122 +1,126 @@ -# Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors -# Licensed under the MIT License: -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# +## Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors +## Licensed under the MIT License: +## +## Permission is hereby granted, free of charge, to any person obtaining a copy +## of this software and associated documentation files (the "Software"), to deal +## in the Software without restriction, including without limitation the rights +## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +## copies of the Software, and to permit persons to whom the Software is +## furnished to do so, subject to the following conditions: +## +## The above copyright notice and this permission notice shall be included in +## all copies or substantial portions of the Software. +## +## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +## THE SOFTWARE. +# @0xb8630836983feed7; - -$import "/capnp/c++.capnp".namespace("capnp"); - -interface Persistent@0xc8cb212fcd9f5691(SturdyRef, Owner) { - # Interface implemented by capabilities that outlive a single connection. A client may save() - # the capability, producing a SturdyRef. The SturdyRef can be stored to disk, then later used to - # obtain a new reference to the capability on a future connection. - # - # The exact format of SturdyRef depends on the "realm" in which the SturdyRef appears. A "realm" - # is an abstract space in which all SturdyRefs have the same format and refer to the same set of - # resources. Every vat is in exactly one realm. All capability clients within that vat must - # produce SturdyRefs of the format appropriate for the realm. - # - # Similarly, every VatNetwork also resides in a particular realm. Usually, a vat's "realm" - # corresponds to the realm of its main VatNetwork. However, a Vat can in fact communicate over - # a VatNetwork in a different realm -- in this case, all SturdyRefs need to be transformed when - # coming or going through said VatNetwork. The RPC system has hooks for registering - # transformation callbacks for this purpose. - # - # Since the format of SturdyRef is realm-dependent, it is not defined here. An application should - # choose an appropriate realm for itself as part of its design. Note that under Sandstorm, every - # application exists in its own realm and is therefore free to define its own SturdyRef format; - # the Sandstorm platform handles translating between realms. - # - # Note that whether a capability is persistent is often orthogonal to its type. In these cases, - # the capability's interface should NOT inherit `Persistent`; instead, just perform a cast at - # runtime. It's not type-safe, but trying to be type-safe in these cases will likely lead to - # tears. In cases where a particular interface only makes sense on persistent capabilities, it - # still should not explicitly inherit Persistent because the `SturdyRef` and `Owner` types will - # vary between realms (they may even be different at the call site than they are on the - # implementation). Instead, mark persistent interfaces with the $persistent annotation (defined - # below). - # - # Sealing - # ------- - # - # As an added security measure, SturdyRefs may be "sealed" to a particular owner, such that - # if the SturdyRef itself leaks to a third party, that party cannot actually restore it because - # they are not the owner. To restore a sealed capability, you must first prove to its host that - # you are the rightful owner. The precise mechanism for this authentication is defined by the - # realm. - # - # Sealing is a defense-in-depth mechanism meant to mitigate damage in the case of catastrophic - # attacks. For example, say an attacker temporarily gains read access to a database full of - # SturdyRefs: it would be unfortunate if it were then necessary to revoke every single reference - # in the database to prevent the attacker from using them. - # - # In general, an "owner" is a course-grained identity. Because capability-based security is still - # the primary mechanism of security, it is not necessary nor desirable to have a separate "owner" - # identity for every single process or object; that is exactly what capabilities are supposed to - # avoid! Instead, it makes sense for an "owner" to literally identify the owner of the machines - # where the capability is stored. If untrusted third parties are able to run arbitrary code on - # said machines, then the sandbox for that code should be designed using Distributed Confinement - # such that the third-party code never sees the bits of the SturdyRefs and cannot directly - # exercise the owner's power to restore refs. See: - # - # http://www.erights.org/elib/capability/dist-confine.html - # - # Resist the urge to represent an Owner as a simple public key. The whole point of sealing is to - # defend against leaked-storage attacks. Such attacks can easily result in the owner's private - # key being stolen as well. A better solution is for `Owner` to contain a simple globally unique - # identifier for the owner, and for everyone to separately maintain a mapping of owner IDs to - # public keys. If an owner's private key is compromised, then humans will need to communicate - # and agree on a replacement public key, then update the mapping. - # - # As a concrete example, an `Owner` could simply contain a domain name, and restoring a SturdyRef - # would require signing a request using the domain's private key. Authenticating this key could - # be accomplished through certificate authorities or web-of-trust techniques. - - save @0 SaveParams -> SaveResults; - # Save a capability persistently so that it can be restored by a future connection. Not all - # capabilities can be saved -- application interfaces should define which capabilities support - # this and which do not. - - struct SaveParams { - sealFor @0 :Owner; - # Seal the SturdyRef so that it can only be restored by the specified Owner. This is meant - # to mitigate damage when a SturdyRef is leaked. See comments above. - # - # Leaving this value null may or may not be allowed; it is up to the realm to decide. If a - # realm does allow a null owner, this should indicate that anyone is allowed to restore the - # ref. - } - struct SaveResults { - sturdyRef @0 :SturdyRef; - } -} - -annotation persistent(interface, field) :Void; -# Apply this annotation to interfaces for objects that will always be persistent, instead of -# extending the Persistent capability, since the correct type parameters to Persistent depend on -# the realm, which is orthogonal to the interface type and therefore should not be defined -# along-side it. +# TODO: removed SturdyRef to build API in C# # -# You may also apply this annotation to a capability-typed field which will always contain a -# persistent capability, but where the capability's interface itself is not already marked -# persistent. +#$import "/capnp/c++.capnp".namespace("capnp"); # -# Note that absence of the $persistent annotation doesn't mean a capability of that type isn't -# persistent; it just means not *all* such capabilities are persistent. +#interface Persistent@0xc8cb212fcd9f5691(SturdyRef, Owner) { +# # Interface implemented by capabilities that outlive a single connection. A client may save() +# # the capability, producing a SturdyRef. The SturdyRef can be stored to disk, then later used to +# # obtain a new reference to the capability on a future connection. +# # +# # The exact format of SturdyRef depends on the "realm" in which the SturdyRef appears. A "realm" +# # is an abstract space in which all SturdyRefs have the same format and refer to the same set of +# # resources. Every vat is in exactly one realm. All capability clients within that vat must +# # produce SturdyRefs of the format appropriate for the realm. +# # +# # Similarly, every VatNetwork also resides in a particular realm. Usually, a vat's "realm" +# # corresponds to the realm of its main VatNetwork. However, a Vat can in fact communicate over +# # a VatNetwork in a different realm -- in this case, all SturdyRefs need to be transformed when +# # coming or going through said VatNetwork. The RPC system has hooks for registering +# # transformation callbacks for this purpose. +# # +# # Since the format of SturdyRef is realm-dependent, it is not defined here. An application should +# # choose an appropriate realm for itself as part of its design. Note that under Sandstorm, every +# # application exists in its own realm and is therefore free to define its own SturdyRef format; +# # the Sandstorm platform handles translating between realms. +# # +# # Note that whether a capability is persistent is often orthogonal to its type. In these cases, +# # the capability's interface should NOT inherit `Persistent`; instead, just perform a cast at +# # runtime. It's not type-safe, but trying to be type-safe in these cases will likely lead to +# # tears. In cases where a particular interface only makes sense on persistent capabilities, it +# # still should not explicitly inherit Persistent because the `SturdyRef` and `Owner` types will +# # vary between realms (they may even be different at the call site than they are on the +# # implementation). Instead, mark persistent interfaces with the $persistent annotation (defined +# # below). +# # +# # Sealing +# # ------- +# # +# # As an added security measure, SturdyRefs may be "sealed" to a particular owner, such that +# # if the SturdyRef itself leaks to a third party, that party cannot actually restore it because +# # they are not the owner. To restore a sealed capability, you must first prove to its host that +# # you are the rightful owner. The precise mechanism for this authentication is defined by the +# # realm. +# # +# # Sealing is a defense-in-depth mechanism meant to mitigate damage in the case of catastrophic +# # attacks. For example, say an attacker temporarily gains read access to a database full of +# # SturdyRefs: it would be unfortunate if it were then necessary to revoke every single reference +# # in the database to prevent the attacker from using them. +# # +# # In general, an "owner" is a course-grained identity. Because capability-based security is still +# # the primary mechanism of security, it is not necessary nor desirable to have a separate "owner" +# # identity for every single process or object; that is exactly what capabilities are supposed to +# # avoid! Instead, it makes sense for an "owner" to literally identify the owner of the machines +# # where the capability is stored. If untrusted third parties are able to run arbitrary code on +# # said machines, then the sandbox for that code should be designed using Distributed Confinement +# # such that the third-party code never sees the bits of the SturdyRefs and cannot directly +# # exercise the owner's power to restore refs. See: +# # +# # http://www.erights.org/elib/capability/dist-confine.html +# # +# # Resist the urge to represent an Owner as a simple public key. The whole point of sealing is to +# # defend against leaked-storage attacks. Such attacks can easily result in the owner's private +# # key being stolen as well. A better solution is for `Owner` to contain a simple globally unique +# # identifier for the owner, and for everyone to separately maintain a mapping of owner IDs to +# # public keys. If an owner's private key is compromised, then humans will need to communicate +# # and agree on a replacement public key, then update the mapping. +# # +# # As a concrete example, an `Owner` could simply contain a domain name, and restoring a SturdyRef +# # would require signing a request using the domain's private key. Authenticating this key could +# # be accomplished through certificate authorities or web-of-trust techniques. +# +# save @0 SaveParams -> SaveResults; +# # Save a capability persistently so that it can be restored by a future connection. Not all +# # capabilities can be saved -- application interfaces should define which capabilities support +# # this and which do not. +# +# struct SaveParams { +# sealFor @0 :Owner; +# # Seal the SturdyRef so that it can only be restored by the specified Owner. This is meant +# # to mitigate damage when a SturdyRef is leaked. See comments above. +# # +# # Leaving this value null may or may not be allowed; it is up to the realm to decide. If a +# # realm does allow a null owner, this should indicate that anyone is allowed to restore the +# # ref. +# } +# struct SaveResults { +# sturdyRef @0 :SturdyRef; +# } +#} +# +#annotation persistent(interface, field) :Void; +## Apply this annotation to interfaces for objects that will always be persistent, instead of +## extending the Persistent capability, since the correct type parameters to Persistent depend on +## the realm, which is orthogonal to the interface type and therefore should not be defined +## along-side it. +## +## You may also apply this annotation to a capability-typed field which will always contain a +## persistent capability, but where the capability's interface itself is not already marked +## persistent. +## +## Note that absence of the $persistent annotation doesn't mean a capability of that type isn't +## persistent; it just means not *all* such capabilities are persistent. +# \ No newline at end of file diff --git a/resource.capnp b/resource.capnp index 50036e5..9529eef 100644 --- a/resource.capnp +++ b/resource.capnp @@ -3,7 +3,9 @@ using CSharp = import "programming_language/csharp.capnp"; $CSharp.namespace("FabAccessAPI.Schema"); -using import "persistent.capnp".Persistent; +# TODO: removed SturdyRef to build API in C# +# using import "persistent.capnp".Persistent; + using import "notify.capnp".Notifiable; using import "interest.capnp".Interestable; using import "claim.capnp".Claimable; diff --git a/resources.capnp b/resources.capnp index 99798e8..6dc6a24 100644 --- a/resources.capnp +++ b/resources.capnp @@ -12,7 +12,7 @@ interface Resources { list @1 () -> ( resources :List(Resource) ); - getByUrn @2 ( urn :Text ) -> ( resource :Resource ); + getByUrn @2 ( urn :Text ) -> ( resource :Resource, dummy :UInt8 = 0 ); # Returns a NULL capability if the resource doesn't exist or an user doesn't have disclose # permission for that resource. diff --git a/utils.capnp b/utils.capnp index befac02..50fd1da 100644 --- a/utils.capnp +++ b/utils.capnp @@ -1,5 +1,8 @@ @0xed0c02f41fea6b5a; +using CSharp = import "programming_language/csharp.capnp"; +$CSharp.namespace("FabAccessAPI.Schema"); + interface L10NString { # Any string type that is intended to be displayed to an user that is more than an identifier to # be used as-is must be able to be localized into the users preferred language. This includes