annotate osx/include/capnp/persistent.capnp @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 0994c39f1e94
children
rev   line source
cannam@62 1 # Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors
cannam@62 2 # Licensed under the MIT License:
cannam@62 3 #
cannam@62 4 # Permission is hereby granted, free of charge, to any person obtaining a copy
cannam@62 5 # of this software and associated documentation files (the "Software"), to deal
cannam@62 6 # in the Software without restriction, including without limitation the rights
cannam@62 7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
cannam@62 8 # copies of the Software, and to permit persons to whom the Software is
cannam@62 9 # furnished to do so, subject to the following conditions:
cannam@62 10 #
cannam@62 11 # The above copyright notice and this permission notice shall be included in
cannam@62 12 # all copies or substantial portions of the Software.
cannam@62 13 #
cannam@62 14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
cannam@62 15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
cannam@62 16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
cannam@62 17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
cannam@62 18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
cannam@62 19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
cannam@62 20 # THE SOFTWARE.
cannam@62 21
cannam@62 22 @0xb8630836983feed7;
cannam@62 23
cannam@62 24 $import "/capnp/c++.capnp".namespace("capnp");
cannam@62 25
cannam@62 26 interface Persistent@0xc8cb212fcd9f5691(SturdyRef, Owner) {
cannam@62 27 # Interface implemented by capabilities that outlive a single connection. A client may save()
cannam@62 28 # the capability, producing a SturdyRef. The SturdyRef can be stored to disk, then later used to
cannam@62 29 # obtain a new reference to the capability on a future connection.
cannam@62 30 #
cannam@62 31 # The exact format of SturdyRef depends on the "realm" in which the SturdyRef appears. A "realm"
cannam@62 32 # is an abstract space in which all SturdyRefs have the same format and refer to the same set of
cannam@62 33 # resources. Every vat is in exactly one realm. All capability clients within that vat must
cannam@62 34 # produce SturdyRefs of the format appropriate for the realm.
cannam@62 35 #
cannam@62 36 # Similarly, every VatNetwork also resides in a particular realm. Usually, a vat's "realm"
cannam@62 37 # corresponds to the realm of its main VatNetwork. However, a Vat can in fact communicate over
cannam@62 38 # a VatNetwork in a different realm -- in this case, all SturdyRefs need to be transformed when
cannam@62 39 # coming or going through said VatNetwork. The RPC system has hooks for registering
cannam@62 40 # transformation callbacks for this purpose.
cannam@62 41 #
cannam@62 42 # Since the format of SturdyRef is realm-dependent, it is not defined here. An application should
cannam@62 43 # choose an appropriate realm for itself as part of its design. Note that under Sandstorm, every
cannam@62 44 # application exists in its own realm and is therefore free to define its own SturdyRef format;
cannam@62 45 # the Sandstorm platform handles translating between realms.
cannam@62 46 #
cannam@62 47 # Note that whether a capability is persistent is often orthogonal to its type. In these cases,
cannam@62 48 # the capability's interface should NOT inherit `Persistent`; instead, just perform a cast at
cannam@62 49 # runtime. It's not type-safe, but trying to be type-safe in these cases will likely lead to
cannam@62 50 # tears. In cases where a particular interface only makes sense on persistent capabilities, it
cannam@62 51 # still should not explicitly inherit Persistent because the `SturdyRef` and `Owner` types will
cannam@62 52 # vary between realms (they may even be different at the call site than they are on the
cannam@62 53 # implementation). Instead, mark persistent interfaces with the $persistent annotation (defined
cannam@62 54 # below).
cannam@62 55 #
cannam@62 56 # Sealing
cannam@62 57 # -------
cannam@62 58 #
cannam@62 59 # As an added security measure, SturdyRefs may be "sealed" to a particular owner, such that
cannam@62 60 # if the SturdyRef itself leaks to a third party, that party cannot actually restore it because
cannam@62 61 # they are not the owner. To restore a sealed capability, you must first prove to its host that
cannam@62 62 # you are the rightful owner. The precise mechanism for this authentication is defined by the
cannam@62 63 # realm.
cannam@62 64 #
cannam@62 65 # Sealing is a defense-in-depth mechanism meant to mitigate damage in the case of catastrophic
cannam@62 66 # attacks. For example, say an attacker temporarily gains read access to a database full of
cannam@62 67 # SturdyRefs: it would be unfortunate if it were then necessary to revoke every single reference
cannam@62 68 # in the database to prevent the attacker from using them.
cannam@62 69 #
cannam@62 70 # In general, an "owner" is a course-grained identity. Because capability-based security is still
cannam@62 71 # the primary mechanism of security, it is not necessary nor desirable to have a separate "owner"
cannam@62 72 # identity for every single process or object; that is exactly what capabilities are supposed to
cannam@62 73 # avoid! Instead, it makes sense for an "owner" to literally identify the owner of the machines
cannam@62 74 # where the capability is stored. If untrusted third parties are able to run arbitrary code on
cannam@62 75 # said machines, then the sandbox for that code should be designed using Distributed Confinement
cannam@62 76 # such that the third-party code never sees the bits of the SturdyRefs and cannot directly
cannam@62 77 # exercise the owner's power to restore refs. See:
cannam@62 78 #
cannam@62 79 # http://www.erights.org/elib/capability/dist-confine.html
cannam@62 80 #
cannam@62 81 # Resist the urge to represent an Owner as a simple public key. The whole point of sealing is to
cannam@62 82 # defend against leaked-storage attacks. Such attacks can easily result in the owner's private
cannam@62 83 # key being stolen as well. A better solution is for `Owner` to contain a simple globally unique
cannam@62 84 # identifier for the owner, and for everyone to separately maintain a mapping of owner IDs to
cannam@62 85 # public keys. If an owner's private key is compromised, then humans will need to communicate
cannam@62 86 # and agree on a replacement public key, then update the mapping.
cannam@62 87 #
cannam@62 88 # As a concrete example, an `Owner` could simply contain a domain name, and restoring a SturdyRef
cannam@62 89 # would require signing a request using the domain's private key. Authenticating this key could
cannam@62 90 # be accomplished through certificate authorities or web-of-trust techniques.
cannam@62 91
cannam@62 92 save @0 SaveParams -> SaveResults;
cannam@62 93 # Save a capability persistently so that it can be restored by a future connection. Not all
cannam@62 94 # capabilities can be saved -- application interfaces should define which capabilities support
cannam@62 95 # this and which do not.
cannam@62 96
cannam@62 97 struct SaveParams {
cannam@62 98 sealFor @0 :Owner;
cannam@62 99 # Seal the SturdyRef so that it can only be restored by the specified Owner. This is meant
cannam@62 100 # to mitigate damage when a SturdyRef is leaked. See comments above.
cannam@62 101 #
cannam@62 102 # Leaving this value null may or may not be allowed; it is up to the realm to decide. If a
cannam@62 103 # realm does allow a null owner, this should indicate that anyone is allowed to restore the
cannam@62 104 # ref.
cannam@62 105 }
cannam@62 106 struct SaveResults {
cannam@62 107 sturdyRef @0 :SturdyRef;
cannam@62 108 }
cannam@62 109 }
cannam@62 110
cannam@62 111 interface RealmGateway(InternalRef, ExternalRef, InternalOwner, ExternalOwner) {
cannam@62 112 # Interface invoked when a SturdyRef is about to cross realms. The RPC system supports providing
cannam@62 113 # a RealmGateway as a callback hook when setting up RPC over some VatNetwork.
cannam@62 114
cannam@62 115 import @0 (cap :Persistent(ExternalRef, ExternalOwner),
cannam@62 116 params :Persistent(InternalRef, InternalOwner).SaveParams)
cannam@62 117 -> Persistent(InternalRef, InternalOwner).SaveResults;
cannam@62 118 # Given an external capability, save it and return an internal reference. Used when someone
cannam@62 119 # inside the realm tries to save a capability from outside the realm.
cannam@62 120
cannam@62 121 export @1 (cap :Persistent(InternalRef, InternalOwner),
cannam@62 122 params :Persistent(ExternalRef, ExternalOwner).SaveParams)
cannam@62 123 -> Persistent(ExternalRef, ExternalOwner).SaveResults;
cannam@62 124 # Given an internal capability, save it and return an external reference. Used when someone
cannam@62 125 # outside the realm tries to save a capability from inside the realm.
cannam@62 126 }
cannam@62 127
cannam@62 128 annotation persistent(interface, field) :Void;
cannam@62 129 # Apply this annotation to interfaces for objects that will always be persistent, instead of
cannam@62 130 # extending the Persistent capability, since the correct type parameters to Persistent depend on
cannam@62 131 # the realm, which is orthogonal to the interface type and therefore should not be defined
cannam@62 132 # along-side it.
cannam@62 133 #
cannam@62 134 # You may also apply this annotation to a capability-typed field which will always contain a
cannam@62 135 # persistent capability, but where the capability's interface itself is not already marked
cannam@62 136 # persistent.
cannam@62 137 #
cannam@62 138 # Note that absence of the $persistent annotation doesn't mean a capability of that type isn't
cannam@62 139 # persistent; it just means not *all* such capabilities are persistent.