gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/README.md (about) 1 # Interface policy 2 3 ## Plug and slot rules 4 5 Declarative rules are used to control what plugs or slots a snap is 6 allowed to use, and if a snap is allowed to use a plug/slot, what other 7 slots/plugs can connect to that plug/slot on this snap. 8 9 These rules are declared as a map which has 6 possible keys: 10 11 - allow-installation 12 - deny-installation 13 - allow-connection 14 - deny-connection 15 - allow-auto-connection 16 - deny-auto-connection 17 18 Each of these keys can either have a static value of true/false or can be a 19 more complex object/list which is “evaluated” by snapd on a device to 20 determine the actual value, be it true or false. 21 22 23 ### Base declaration and snap declarations 24 25 The rules defined in the snapd interfaces source code (via setting 26 `commonInterface.baseDeclarationSlots/Plugs`) form the 27 “base declaration” and can be overridden by per-snap rules in the 28 snap store published via the per-snap `snap-declaration` assertions, 29 which make it possible for a store to alter the policy hardcoded in 30 snapd. For example, a store assertion is typically used to grant 31 auto-connection to some plugs of a specific application where this is 32 deemed reasonable or safe (such as auto-connecting the `camera` 33 interface in a web-streaming application). 34 35 ### Basic evaluation and precedence 36 37 The default value of the `allow-*` keys when not otherwise specified is `true` 38 and the default value of `deny-*` keys when not otherwise specified is `false`. 39 Matching `deny-*` constraints override/take precedence over `allow-*` 40 constraints specified in the same declaration. The order of evaluation of rules 41 is the following (execution stops as soon as a matching rule is found, meaning 42 that the topmost elements in this list have higher priority): 43 44 - `deny-*` keys in plug snap-declaration rule 45 - `allow-*` keys in plug snap-declaration rule 46 - `deny-*` keys in slot snap-declaration rule 47 - `allow-*` keys in slot snap-declaration rule 48 - `deny-*` keys in plug base-declaration rule 49 - `allow-*` keys in plug base-declaration rule 50 - `deny-*` keys in slot base-declaration rule 51 - `allow-*` keys in slot base-declaration rule 52 53 In other words, snap-declaration (store) rules have priority over 54 base-declaration rules; then, plug rules have priority over slot rules, and 55 finally, deny rules have priority over allow rules. 56 57 58 ### allow-installation 59 60 The `allow-installation` key is evaluated when the snap is being installed. If 61 this evaluates to false, the snap cannot be installed if an interface plug or 62 slot for which `allow-installation` evaluated to `false` exists in the snap. An 63 example would be the `snapd-control` interface, which has in the 64 base-declaration the static `allow-installation: false` rule for plugs: 65 66 snapd-control: 67 allow-installation: false 68 deny-auto-connection: true 69 70 If a snap does not plug `snapd-control` then this rule does not apply, but if 71 the snap does declare a `snapd-control` plug and there are no assertions in the 72 store for this snap about allowing `snapd-control`, then snap installation will 73 fail. 74 75 Snap interfaces that have `allow-installation` set to `false` for their plugs 76 in the base-declaration are said to be “**super-privileged**”, meaning they 77 cannot be used at all without a snap-declaration assertion. 78 79 80 ### allow-connection 81 82 The `allow-connection` key controls whether an API/manual connection 83 is permitted at all and usually is used to ensure that only 84 “compatible” plugs and slots are connected to each other. A great 85 example is the content interface, where the following (abbreviated) 86 rule from the base-declaration is used to ensure that a candidate plug 87 and slot content interface have matching `content` attribute values: 88 89 allow-connection: 90 plug-attributes: 91 content: $SLOT(content) 92 93 This can be read as `allow-connection` evaluating to `true` only when the plug 94 has an attribute `content` with the same value as the attribute `content` in 95 the slot. That is to say, these plug and slots are compatible because `content` 96 does match for the plug and slot: 97 98 # in the snap providing the content: 99 slots: 100 foo-content: 101 interface: content 102 content: specific-files 103 104 # in the snap consuming the content: 105 plugs: 106 foo-content: 107 interface: content 108 content: specific-files 109 110 While the following plug and slots are not compatible: 111 112 slots: 113 foo-content: 114 interface: content 115 content: other-files 116 117 plugs: 118 foo-content: 119 interface: content 120 content: specific-files 121 122 123 ### allow-auto-connection 124 125 The allow-auto-connection key is the final key considered when snapd is 126 evaluating the automatic connection of interface plugs and slots. If this key 127 evaluates to `true`, then this plug/slot combination is considered a valid 128 candidate for automatic connection. In this context allow-connection is ignored. 129 130 An automatic connection will happen normally only if there is one single 131 candidate combination with a slot for a given plug. 132 133 134 ### Supported rule constraints 135 136 Each of the keys seen before (`allow/deny-installation`, 137 `allow/deny-connection`, and `allow/deny-auto-connection`) has a set of 138 sub-keys that can be used as rules with each constraint. The authoritative 139 place where this information comes from is inside snapd in the `asserts` 140 package, specifically the file `ifacedecls.go` is the main place where these 141 are defined. 142 143 In `allow-connection` or `allow-auto-connection` constraints about snap type, 144 snap ID and publisher can only be specified for the other side snap (e.g. a 145 slot-side `allow-connection` constraint can only specify plug-snap-type, 146 plug-snap-id, plug-snap-publisher). 147 148 For the `plug-snap-type` and `slot-snap-type` rules there are 4 149 possible values: `core`, `gadget`, `kernel`, and `app`. The `core` snap 150 type refers to whichever snap is providing snapd on the system and 151 therefore the system interface slots, either the `core` snap or `snapd` 152 snap (typically `core` snap on UC16 devices, `snapd` snap on UC18+ 153 systems, and either on classic systems depending on re-exec logic). 154 155 The `on-store`, `on-brand`, and `on-model` rules are not generally hardcoded in 156 the snapd interfaces, but are specified in store assertions; they are known as 157 “device context constraints” and are primarily used to ensure that a given 158 rule only applies to a device with a serial assertion (and thus model 159 assertion) from a given brand. This is because if the assertion and snap from a 160 brand store were copied to a non-branded device, the assertion could still be 161 acknowledged by the device and the snap installed, but the assertion would not 162 operate, and snap connections would not take place as they do on the branded 163 device. 164 165 The `plug-names` and `slot-names` rules are also only used in store assertions. 166 They refer to the naming of a plug or slot when that slot is scoped globally 167 with a name other than the generic interface name. 168 For example this assertion: 169 170 plugs: 171 gpio: 172 allow-auto-connection: 173 slot-names: [ gpio1 ] 174 plug-names: [ gpio-red-led ] 175 176 only allows the plugging snap to have its plug named `gpio-red-led` 177 auto-connected to a gpio slot named `gpio1`. 178 179 180 ### Rule evaluation 181 182 #### Greedy connection / single slot rule 183 184 The first rule about whether an automatic connection happens between a plug and 185 a slot has to do with “arity” or how many slots a given plug is being 186 considered to connect to and vice versa. This is expressed with the 187 `slots-per-plug` and `plugs-per-slot` rules, with the default value of 188 `plugs-per-slot` being “`*`” meaning any number of plugs can be connected to a 189 specific slot. The default value of `slots-per-plug` is “`1`”, however, meaning that a 190 plug can in general without a special snap-declaration only automatically 191 connect to one slot. All that is to say, if there are multiple candidate slots, 192 in the default case a plug will auto-connect to neither of them and 193 snapd will issue a warning. 194 195 See also [this forum 196 post](https://forum.snapcraft.io/t/plug-slot-declaration-rules-greedy-plugs/12438) 197 which was written when this logic was first implemented. 198 199 200 #### Maps and Lists 201 202 The next rule about evaluating snap-declaration assertions is that maps are 203 treated as logical ANDs where each key in the map must individually evaluate to 204 `true` and lists are treated as logical ORs where only one of the elements of 205 the list must evaluate to `true`. With the following example assertion, 206 order 207 for the `serial-port` plug in this snap to auto-connect, either the first 208 element of the list must evaluate to `true` or the second element of the list 209 must evaluate to `true` (or they could both theoretically evaluate to `true`, 210 but this is impossible in practice since the slots can only come from gadgets 211 and so to match both the system would have to have two gadget snaps installed 212 simultaneously which is impossible). 213 214 plugs: 215 serial-port: 216 allow-auto-connection: 217 - 218 on-store: 219 - my-app-store 220 plug-names: 221 - serial-rf-nic 222 slot-attributes: 223 path: /dev/serial-port-rfnic 224 slot-names: 225 - serial-rf-nic 226 slot-snap-id: 227 - Cx4J8ADDq8xULNaAjO7mQid75ru4rObB 228 - 229 on-store: 230 - my-app-store 231 plug-names: 232 - serial-rf-nic 233 slot-attributes: 234 path: /dev/serial-port-rfnic 235 slot-names: 236 - serial-rf-nic 237 slot-snap-id: 238 - WabnwLoV48BCMj8NoOetmdxFFMxDsPGb 239 240 For the first element of the allow-auto-connection list to evaluate to 241 `true`, the following things must be true: 242 243 - The device must be on a brand device in `my-app-store` AND 244 - The plug name must be `serial-rf-nic` AND 245 - The slot name must be `serial-rf-nic` AND 246 - The slot must declare an attribute, `path`, with the value 247 `/dev/serial-port-rfnic` AND 248 - The slot must come from a snap with a snap ID of 249 `Cx4J8ADDq8xULNaAjO7mQid75ru4rObB` 250 251 The above is also true for the second element of the allow-auto-connection list. 252 253 An equivalent way to write an assertion that works in exactly the same way would be: 254 255 plugs: 256 serial-port: 257 allow-auto-connection: 258 on-store: 259 - my-app-store 260 plug-names: 261 - serial-rf-nic 262 slot-attributes: 263 path: /dev/serial-port-rfnic 264 slot-names: 265 - serial-rf-nic 266 slot-snap-id: 267 - Cx4J8ADDq8xULNaAjO7mQid75ru4rObB 268 - WabnwLoV48BCMj8NoOetmdxFFMxDsPGb 269 270 The chief difference here is that instead of having a list of two maps, we 271 instead have a single map, and the key which changes for the two gadgets is the 272 `slot-snap-id` which now has two values in a list. In this case, the slot snap 273 ID must be one of the snap IDs in the list in order for the `slot-snap-id` rule 274 to evaluate to true. So the following things must be true: 275 276 - The device must be on a brand device in `my-app-store` AND 277 - The plug name must be `serial-rf-nic` AND 278 - The slot-name must be `serial-rf-nic` AND 279 - The slot must declare an attribute, `path`, with the value 280 `/dev/serial-port-rfnic` AND 281 - The slot must come from a snap with a snap ID of any of the following elements: 282 - `Cx4J8ADDq8xULNaAjO7mQid75ru4rObB`, OR 283 - `WabnwLoV48BCMj8NoOetmdxFFMxDsPGb` 284 285 Lists and maps can also be used as values for attributes under 286 plug/slot-attributes constraints. A map will match only if the attribute value 287 contains all the entries in the constraints map with the same values (extra 288 attribute elements are ignored). 289 A list will match against a non-list attribute value if the value matches any 290 of the list elements. A list will match against a list attribute value if all 291 the elements in the attribute list value in turn match something in the list. 292 This means, for example, a constraint list of value constraints will match a list 293 of attribute scalars if the two groups of values match as a set (order doesn't 294 matter). 295 296 297 #### Attribute constraints and special matches and variables 298 299 Plug/slot-attributes string value constraints are interpreted as regexps 300 (wrapped implicitly in `^$` anchors), unless they are one of the special forms 301 starting with `$`. 302 303 The special forms starting with `$` currently consist of: 304 305 - `$SLOT_PUBLISHER_ID`, `$PLUG_PUBLISHER_ID`: these can be specified in the 306 `plug-publisher-id` and `slot-publisher-id` constraints respectively and are 307 used from the plug side and slot side of a declaration to refer to the 308 publisher-id of the other side of the connection. 309 - `$PLUG()`, `$SLOT()`: similar to the above, but used in the `plug-attributes` 310 and `slot-attributes` constraints for specifying attributes instead of 311 publisher-ids. 312 - `$MISSING`: used in the `plug-attributes` and `slot-attributes` constraints 313 to match when the attribute set to `$MISSING` is not specified in the snap. 314 315 For example, these features are used in the base-declaration for the `content` 316 interface to express that a connection is only allowed when the attribute value 317 of the verbatim “content” attribute on the slot side is the same as the plug 318 side and that auto-connection should only take place by default when the plug 319 publisher ID is the same as the slot publisher ID (unless this is overridden by 320 a store assertion): 321 322 content: 323 allow-installation: 324 slot-snap-type: 325 - app 326 - gadget 327 allow-connection: 328 plug-attributes: 329 content: $SLOT(content) 330 allow-auto-connection: 331 plug-publisher-id: 332 - $SLOT_PUBLISHER_ID 333 plug-attributes: 334 content: $SLOT(content) 335