| // Copyright 2016 The LUCI Authors. All rights reserved. |
| // Use of this source code is governed under the Apache License, Version 2.0 |
| // that can be found in the LICENSE file. |
| |
| syntax = "proto3"; |
| |
| package swarming.config; |
| |
| option go_package = "go.chromium.org/luci/swarming/proto/config;configpb"; |
| |
| import "go.chromium.org/luci/common/proto/options.proto"; |
| |
| option (luci.file_metadata) = { |
| doc_url: "https://luci-config.appspot.com/schemas/services/swarming:bots.cfg"; |
| }; |
| |
| // Schema for bots.cfg service config file in luci-config. |
| // |
| // It defines a function bot_id => (required credentials, trusted_dimensions, |
| // config), where |
| // * "bot_id" is identifier of a bot as sent by the bot itself (usually |
| // machine hostname, short one, not FQDN) |
| // * "required credentials" describes how server should authenticate calls |
| // from the bot. |
| // * "trusted_dimensions" is a set of dimension set by the server itself. |
| // Such dimensions can't be spoofed by the bot. |
| // * "config" is any additional bot configuration. |
| // |
| // Connections from bots that do not appear in this config are rejected. |
| // |
| // The default config (used if bots.cfg is missing) represents IP-whitelist only |
| // authentication, as was used before bots.cfg was implemented: |
| // |
| // bot_group { |
| // auth { |
| // ip_whitelist: "<swarming-app-id>-bots" |
| // } |
| // } |
| message BotsCfg { |
| // List of dimension names that are provided by the server. |
| // |
| // If bot attempts to set such dimension, it'll be ignored. Trusted dimensions |
| // are defined through bot_group configs below. Swarming users can trust such |
| // dimensions, since they are set by the server based on validated credentials |
| // (unlike other dimensions that can be arbitrary defined by the bot itself). |
| repeated string trusted_dimensions = 1; |
| |
| // A list of groups of bots. Each group defines a bunch of bots that all |
| // have same dimensions and authenticate in the same way. |
| // |
| // The order of entries here is irrelevant. The server uses the following |
| // search algorithm when trying to pick a group for a bot with some bot_id: |
| // 1) First it tries to find a direct match: a group that lists the bot in |
| // bot_id field. |
| // 2) Next it tries to find a group with matching bot_id_prefix. The config |
| // validation process makes sure prefixes do not "intersect", so there |
| // will be at most one matching group. |
| // 3) Finally, if there's a group with no defined bot_id or bot_id_prefix |
| // fields (the "default" group), the bot is categorized to that group. |
| // If there's no such group, the connection from the bot is rejected. |
| // Config validation process ensures there can be only one such group. |
| repeated BotGroup bot_group = 2; |
| } |
| |
| |
| // A group of bots that share authentication method, dimensions and owners. |
| // |
| // Union of bot_id and bot_id_prefix define a set of bots that belong to this |
| // group. The rest of the fields define properties of this group. |
| // |
| // If bot_id and bot_id_prefix are both missing, the group defines all bots that |
| // didn't fit into other groups. There can be only one such "default" group. |
| // |
| // NOTE: Swarming allows 'derivative' bots where multiple bots run on the same |
| // host machine in some sort of container (such as Docker containers) and SHARE |
| // A SINGLE CREDENTIAL. These bots have hostnames such as 'hostmachine--001', |
| // where the "--001" suffix indicates which of the contained bots on |
| // 'hostmachine' it is. When Swarming checks the bot affiliation for this |
| // contained machine, it checks ONLY the 'hostmachine' portion. This means that |
| // if your contained bot is 'vm10-vlan2--001', it would match: |
| // `bot_id: "vm10-vlan2` |
| // `bot_id: "vm{0...100}-vlan2` |
| // `bot_id_prefix: "vm10-vlan` |
| // but would NOT match: |
| // `bot_id: "vm10-vlan2--001` |
| // `bot_id_prefix: "vm10-vlan2-` |
| // `bot_id_prefix: "vm10-vlan2--` |
| // |
| // TODO(vadimsh): Introduce explicit field "use_as_default" instead. |
| message BotGroup { |
| reserved 3; |
| |
| // Explicit enumeration of bot IDs belonging to this group. |
| // |
| // It supports subset of bash brace expansion syntax, in particular ranges |
| // and lists. For example: |
| // * vm{1..3}-m1 will expand into vm1-m1, vm2-m1 and vm3-m1. |
| // * vm{100,150,200}-m1 will expand into vm100-m1, vm150-m1 and vm200-m1. |
| // |
| // There can be only one "{...}" section in the string. |
| repeated string bot_id = 1; |
| |
| // A prefix to match against bot ID string. |
| repeated string bot_id_prefix = 2; |
| |
| //////////////////////// |
| |
| // Defines authentication methods for bots from this group. |
| // |
| // Evaluated sequentially until first match. |
| repeated BotAuth auth = 20; |
| |
| // Emails of owners of these bots. Optional. |
| repeated string owners = 21; |
| |
| // List of dimensions to assign to these bots. |
| // |
| // Each dimension is a "<key>:<value>" pair. |
| repeated string dimensions = 22; |
| |
| // Path to an additional config script to inject into the swarming bot upon |
| // handshake. |
| // |
| // The path is relative to 'scripts/' directory in the service config repo. |
| string bot_config_script = 23; |
| |
| // The actual body of the config script to inject into the swarming bot upon |
| // handshake (in whatever encoding it happened to be in the config repo). |
| // |
| // For internal use (unless you fancy writing python scripts as single line |
| // escaped text proto string). If present, overrides 'bot_config_script'. |
| bytes bot_config_script_content = 25; |
| |
| // A service account to use on bots when authenticating calls to various |
| // system-level services (like Isolate and CIPD), required for correct |
| // operation of the bot. |
| // |
| // Tasks will be able to access this account too, but it is not recommended |
| // and should be used extremely rare. |
| // |
| // If set to a service account email (*@*.iam.gserviceaccount.com), bots will |
| // use this account, generating access token through Swarming server. For this |
| // to work, the server account (<app-id>@appspot.gserviceaccount.com) must |
| // have "serviceAccountActor" IAM role set on the account. |
| // |
| // If set to a special string "bot", bots will use exact same token they use |
| // when authenticating calls to Swarming server itself. This works only if |
| // bots use OAuth for authentication (see 'require_service_account' in |
| // BotAuth). This mode exists for cases when proliferation of various service |
| // accounts is undesirable. Note that in this mode Swarming processes won't be |
| // able to request a system account token with some new scopes: they get exact |
| // same token as returned by get_authentication_headers bot_config.py hook. |
| // |
| // If not set, bots will not use authentication at all. |
| string system_service_account = 24; |
| } |
| |
| |
| // Defines what kind of authentication to perform when handling requests from |
| // bots belonging to some bot group. |
| // |
| // The following combinations are valid: |
| // * Either one of require_* alone. |
| // * IP whitelist alone. |
| // * IP + require_luci_machine_token: requires both to pass. |
| // * IP + require_service_account: requires both to pass. |
| // * IP + require_gce_vm_token: requires both to pass. |
| // |
| // Next ID: 6. |
| message BotAuth { |
| // See require_gce_vm_token below. |
| message GCE { |
| string project = 1; |
| } |
| |
| // If true, log an error (but proceed) if this method didn't succeed. |
| // |
| // This field is totally optional and makes sense only when there are more |
| // than one auth method. Affects only logging levels. |
| // |
| // Doesn't apply to methods that were skipped because some method before them |
| // succeeded. Thus methods that have 'log_if_failed' should be in front of |
| // BotGroup.auth list. |
| // |
| // This is useful when migrating from one auth method to another to verify |
| // the new method is used in 100% of cases, while still keeping a fallback |
| // to an old method. |
| bool log_if_failed = 5; |
| |
| // If true, the bot should provide valid X-Luci-Machine-Token header. |
| // |
| // The machine FQDN embedded in the token should have hostname equal to the |
| // bot_id. |
| bool require_luci_machine_token = 1; |
| |
| // If set, the bot should use OAuth access token belonging to any of these |
| // service accounts. |
| // |
| // The token should have "https://www.googleapis.com/auth/userinfo.email" |
| // scope. |
| repeated string require_service_account = 2; |
| |
| // If set, the bot should provide valid X-Luci-Gce-Vm-Token header. |
| // |
| // This header should contain JWT with signed VM metadata with the following |
| // expectations: |
| // * Audience matches https://[*-dot-]<app>.appspot.com |
| // * google.compute_engine.project_id field matches the value of 'project'. |
| // * instance_name matches bot_id reported by the bot (case insensitive). |
| GCE require_gce_vm_token = 4; |
| |
| // If set, defines an IP whitelist name (in auth_service database) with a set |
| // of IPs allowed to be used by the bots in this group. |
| // |
| // Works in conjunction with other checks, e.g. if require_luci_machine_token |
| // is true, both valid X-Luci-Machine-Token and a whitelisted IP are needed to |
| // successfully authenticate. |
| // |
| // Can also be used on its own (when all other fields are empty). In that case |
| // the IP whitelist is the primary authentication mechanism. Note that in this |
| // case all bots that share the IP whitelist are effectively in a single trust |
| // domain (any bot can pretend to be some other bot). |
| string ip_whitelist = 3; |
| } |