go.chromium.org/luci@v0.0.0-20250314024836-d9a61d0730e6/tokenserver/api/minter/v1/token_minter.proto (about) 1 // Copyright 2016 The LUCI Authors. All rights reserved. 2 // Use of this source code is governed under the Apache License, Version 2.0 3 // that can be found in the LICENSE file. 4 5 syntax = "proto3"; 6 7 package tokenserver.minter; 8 9 option go_package = "go.chromium.org/luci/tokenserver/api/minter/v1;minter"; 10 11 import "google/protobuf/timestamp.proto"; 12 13 import "go.chromium.org/luci/server/auth/delegation/messages/delegation.proto"; 14 import "go.chromium.org/luci/tokenserver/api/machine_token.proto"; 15 16 17 // Supported ways of singing the request. 18 enum SignatureAlgorithm { 19 UNKNOWN_ALGO = 0; // used if the field is not initialized 20 SHA256_RSA_ALGO = 1; // matches x509's sha256WithRSAEncryption 21 } 22 23 24 // Possible kinds of fatal errors. 25 // 26 // Non fatal errors are returned as grpc.Internal errors instead. 27 enum ErrorCode { 28 SUCCESS = 0; 29 UNSUPPORTED_SIGNATURE = 1; // used signature_algorithm is not supported 30 UNSUPPORTED_TOKEN_TYPE = 2; // requested token_type is not supported 31 BAD_TIMESTAMP = 3; // issued_at field is wrong 32 BAD_CERTIFICATE_FORMAT = 4; // malformed or unsupported certificate 33 BAD_SIGNATURE = 5; // signature doesn't match or can't be verified 34 UNTRUSTED_CERTIFICATE = 6; // invalid certificate or can't verify it yet 35 BAD_TOKEN_ARGUMENTS = 7; // FQDN or Scopes are invalid or not whitelisted 36 MACHINE_TOKEN_MINTING_ERROR = 8; // unspecified fatal error when minting a machine token 37 } 38 39 40 // Used by MintServiceAccountToken. 41 enum ServiceAccountTokenKind { 42 SERVICE_ACCOUNT_TOKEN_UNSPECIFIED = 0; 43 SERVICE_ACCOUNT_TOKEN_ACCESS_TOKEN = 1; // ask for an OAuth2 access token 44 SERVICE_ACCOUNT_TOKEN_ID_TOKEN = 2; // ask for an OpenID ID token 45 } 46 47 48 // TokenMinter implements main API of the token server. 49 // 50 // It provides an interface for generating: 51 // 52 // * Machine tokens: short lived stateless tokens used in Swarming bot 53 // authentication protocol. They are derived from PKI keys deployed on bots, 54 // and consumed primarily by Swarming. See MintMachineToken. 55 // * Delegation tokens: these are involved whenever a service calls other 56 // service on behalf of a user. They are passed via 'X-Delegation-Token-V1' 57 // HTTP header along with a credentials of the impersonating user. 58 // See MintDelegationToken. 59 // * OAuth2 access tokens of project-scoped accounts: these are OAuth2 access 60 // tokens that represents an identity associated with a LUCI project. See 61 // MintProjectToken. 62 // * Service accounts tokens: these are OAuth2 access tokens and ID tokens of 63 // service accounts "residing" within various LUCI projects. They are 64 // ultimately used by LUCI tasks as task service accounts. 65 // See MintServiceAccountToken. 66 // 67 // RPCs that were deprecated and removed: 68 // 69 // * MintOAuthTokenGrant and MintOAuthTokenViaGrant: were deprecated by 70 // MintServiceAccountToken. Used (also now removed) service_accounts.cfg 71 // config file. 72 service TokenMinter { 73 // MintMachineToken generates a new token for an authenticated machine. 74 // 75 // It checks that provided certificate was signed by some trusted CA, and it 76 // is still valid (non-expired and hasn't been revoked). It then checks that 77 // the request was signed by the corresponding private key. Finally it checks 78 // that the caller is authorized to generate requested kind of token. 79 // 80 // If everything checks out, it generates and returns a new machine token. 81 // 82 // On fatal error it returns detailed error response via same 83 // MintMachineTokenResponse. On transient errors it returns generic 84 // grpc.Internal error. 85 rpc MintMachineToken(MintMachineTokenRequest) returns (MintMachineTokenResponse); 86 87 // MintDelegationToken generates a new bearer delegation token. 88 // 89 // Such token can be sent in 'X-Delegation-Token-V1' header (alongside regular 90 // credentials like OAuth2 access token) to convey that the caller should be 91 // authentication as 'delegated_identity' specified in the token. 92 // 93 // The delegation tokens are subject to multiple restrictions (embedded in 94 // the token): 95 // * They have expiration time. 96 // * They are usable only if presented with a credential of someone from 97 // the 'audience' list. 98 // * They are usable only on services specified in the 'services' list. 99 // 100 // The token server must be configured in advance with all expected 101 // combinations of (caller identity, delegated identity, audience, service) 102 // tuples. See DelegationRule in config.proto. 103 rpc MintDelegationToken(MintDelegationTokenRequest) returns (MintDelegationTokenResponse); 104 105 // MintProjectToken mints an OAuth2 access token that represents an identity 106 // associated with a LUCI project. 107 // 108 // Project-scoped tokens prevent accidental cross-project identity confusion 109 // when LUCI services access project specific resources such as a source code 110 // repository. 111 rpc MintProjectToken(MintProjectTokenRequest) returns (MintProjectTokenResponse); 112 113 // MintServiceAccountToken mints an OAuth2 access token or OpenID ID token 114 // that belongs to some service account using LUCI Realms for authorization. 115 // 116 // As an input it takes a service account email and a name of a LUCI Realm the 117 // caller is operating in. To authorize the call the token server checks the 118 // following conditions: 119 // 1. The caller has luci.serviceAccounts.mintToken permission in the 120 // realm, allowing them to "impersonate" all service accounts belonging 121 // to this realm. 122 // 2. The service account has luci.serviceAccounts.existInRealm permission 123 // in the realm. This makes the account "belong" to the realm. 124 // 3. Realm's LUCI project is allowed to impersonate this service account: 125 // a. Legacy approach being deprecated: realm's LUCI project is NOT listed 126 // in `use_project_scoped_account` set in project_owned_accounts.cfg 127 // global config file, but it has service accounts associated with it 128 // there via `mapping` field. In that case LUCI Token Server will check 129 // `mapping` and then use its own service account when minting tokens. 130 // b. New approach being rolled out: realm's LUCI project is listed in 131 // `use_project_scoped_account` set in project_owned_accounts.cfg 132 // global config file. In that case LUCI Token Server will use 133 // project-scoped account associated with this LUCI project when 134 // minting service account tokens. This essentially shifts mapping 135 // between LUCI projects and service accounts they can use into 136 // service account IAM policies. 137 // 138 // Check (3) makes sure different LUCI projects can't arbitrarily use each 139 // others accounts by adding them to their respective realms.cfg. See also 140 // comments for ServiceAccountsProjectMapping in api/admin/v1/config.proto. 141 rpc MintServiceAccountToken(MintServiceAccountTokenRequest) returns (MintServiceAccountTokenResponse); 142 } 143 144 145 //////////////////////////////////////////////////////////////////////////////// 146 // Machine tokens. 147 148 149 // MintMachineTokenRequest wraps a serialized and signed MachineTokenRequest 150 // message. 151 message MintMachineTokenRequest { 152 // The protobuf-serialized MachineTokenRequest message, signed by the private 153 // key that matches MachineTokenRequest.certificate. 154 // 155 // We have to send it as a byte blob to avoid dealing with possible protobuf 156 // serialization inconsistencies when checking the signature. 157 bytes serialized_token_request = 1; 158 159 // The signature of 'serialized_token_parameters' blob. 160 // 161 // See MachineTokenRequest.signature_algorithm for exact meaning. 162 bytes signature = 2; 163 } 164 165 166 // MachineTokenRequest contains the actual request parameters. 167 message MachineTokenRequest { 168 reserved 5; 169 170 // The certificate that identifies a caller (as ASN1-serialized blob). 171 // 172 // It will be used to extract machine FQDN (it's CN of the cert) and CA name 173 // to use to check the cert. 174 bytes certificate = 1; 175 176 // The signature algorithm used to sign this request. 177 // 178 // Defines what's in MintMachineTokenRequest.signature field. 179 SignatureAlgorithm signature_algorithm = 2; 180 181 // Timestamp when this request was created, by the issuer clock. 182 google.protobuf.Timestamp issued_at = 3; 183 184 // The token type being requested. 185 // 186 // Defines what fields of the response are set. 187 MachineTokenType token_type = 4; 188 } 189 190 191 // MintMachineTokenResponse is returned by MintMachineToken if the server 192 // processed the request. 193 // 194 // It's returned even if server refuses to mint a token. It contains the error 195 // details in that case. 196 message MintMachineTokenResponse { 197 // Possible kinds of fatal errors. 198 // 199 // Non fatal errors are returned as grpc.Internal errors instead. 200 ErrorCode error_code = 1; 201 202 // Optional detailed error message. 203 string error_message = 2; 204 205 // On success (SUCCESS error code) contains the produced token. 206 MachineTokenResponse token_response = 3; 207 208 // Identifier of the service and its version that produced the response. 209 // 210 // Set for both successful responses and errors. On success, it is identical 211 // to token_response.service_version. 212 string service_version = 4; 213 } 214 215 216 // MachineTokenResponse contains a token requested by MachineTokenRequest. 217 message MachineTokenResponse { 218 reserved 1, 20; 219 220 // Identifier of the service and its version that produced the token. 221 // 222 // Has the form "<app-id>/<module-version>". Reported to the monitoring by 223 // the client. This is _not_ a part of the token. 224 string service_version = 2; 225 226 // The generated token. 227 // 228 // The exact field set here depends on a requested type of the token, see 229 // MachineTokenRequest.token_type. 230 oneof token_type { 231 LuciMachineToken luci_machine_token = 21; 232 } 233 } 234 235 236 // LuciMachineToken is short lived machine token. 237 // 238 // It is understood only by LUCI backends. It is a bearer token, that embeds 239 // machine hostname and details about the machine certificate it was issued for. 240 // It has short lifetime (usually 1h). 241 // 242 // It is expected to be sent to backends in 'X-Luci-Machine-Token' HTTP header. 243 // 244 // The token here is supposed to be treated as an opaque base64-encoded blob, 245 // but in reality it is serialized MachineTokenEnvelope, see machine_token.proto 246 // and read the comment there for more info about the token format. 247 message LuciMachineToken { 248 string machine_token = 1; // the actual token 249 google.protobuf.Timestamp expiry = 2; // when the token expires 250 } 251 252 253 //////////////////////////////////////////////////////////////////////////////// 254 // Delegation tokens. 255 256 257 // MintDelegationTokenRequest is passed to MintDelegationToken. 258 message MintDelegationTokenRequest { 259 // Identity whose authority is delegated. 260 // 261 // A string of the form "user:<email>" or a special token "REQUESTOR" that 262 // means to delegate caller's own identity. The token server will check its 263 // ACLs to make sure the caller is authorized to impersonate this identity. 264 // 265 // Required. 266 string delegated_identity = 1; 267 268 // How long the token should be considered valid (in seconds). 269 // 270 // Default is 3600 sec. 271 int64 validity_duration = 2; 272 273 // Who will be able to use the new token. 274 // 275 // Each item can be an identity string (e.g. "user:<email>"), a "group:<name>" 276 // string, special "*" string which means "Any bearer can use the token", or 277 // "REQUESTOR" string which means "Whoever is making this call can use the 278 // token". 279 // 280 // This is semantically is a set, the order of elements doesn't matter. 281 // 282 // Required. 283 repeated string audience = 3; 284 285 // What services should accept the new token. 286 // 287 // List of LUCI services (specified as service identities, e.g. 288 // "service:app-id" or as https:// root URLs e.g. "https://<host>") that 289 // should accept this token. May also contain special "*" string, which 290 // means "All LUCI services". 291 // 292 // This is semantically is a set, the order of elements doesn't matter. 293 // 294 // Required. 295 repeated string services = 4; 296 297 // Optional reason why the token is created. 298 // 299 // Used only for logging and auditing purposes. Doesn't become part of the 300 // token. 301 string intent = 5; 302 303 // Arbitrary key:value pairs embedded into the token by whoever requested it. 304 // Convey circumstance of why the token is created. 305 // 306 // Services that accept the token may use them for additional authorization 307 // decisions. Please use extremely carefully, only when you control both sides 308 // of the delegation link and can guarantee that services involved understand 309 // the tags. 310 repeated string tags = 6; 311 } 312 313 314 // MintDelegationTokenResponse is returned by MintDelegationToken on success. 315 // 316 // Errors are returned via standard gRPC codes. 317 message MintDelegationTokenResponse { 318 // The actual base64-encoded signed token. 319 string token = 1; 320 321 // Same data as in 'token' in deserialized form, just for convenience. 322 // 323 // Mostly for JSON encoding users, since they may not understand proto-encoded 324 // tokens. 325 messages.Subtoken delegation_subtoken = 2; 326 327 // Identifier of the service and its version that produced the token. 328 // 329 // Has the form "<app-id>/<module-version>". This is _not_ part of the token. 330 // Used only for logging and monitoring. 331 string service_version = 3; 332 } 333 334 335 //////////////////////////////////////////////////////////////////////////////// 336 // Service account tokens. 337 338 339 // MintProjectTokenRequest is passed to MintProjectToken. 340 message MintProjectTokenRequest { 341 // Luci project to which this token will be bound. 342 string luci_project = 1; 343 344 // Requested OAuth scopes for the token. 345 repeated string oauth_scope = 2; 346 347 // Minimum token validity duration in seconds. 348 int64 min_validity_duration = 3; 349 350 // Arbitrary key:value pairs describing circumstances of this call. 351 // 352 // Used only for logging and auditing purposes. Not involved in authorization. 353 repeated string audit_tags = 4; 354 } 355 356 357 // MintProjectTokenResponse is returned by MintProjectToken. 358 message MintProjectTokenResponse { 359 // Full service account email. 360 string service_account_email = 1; 361 362 // OAuth access token. 363 string access_token = 2; 364 365 // Token expiration timestamp. 366 google.protobuf.Timestamp expiry = 3; 367 368 // Identifier of the service and its version that produced the token. 369 // 370 // Has the form "<app-id>/<module-version>". Used only for logging and 371 // monitoring. 372 string service_version = 4; 373 } 374 375 376 // MintServiceAccountTokenRequest is passed to MintServiceAccountToken. 377 message MintServiceAccountTokenRequest { 378 // What kind of a token is being requested. Required. 379 ServiceAccountTokenKind token_kind = 1; 380 // Email of a service account to grab the token for. Required. 381 string service_account = 2; 382 // A LUCI realm to use to authorize the call. Required. 383 string realm = 3; 384 385 // A list of scopes the OAuth2 access token should have. 386 // 387 // Must be set if token_kind is SERVICE_ACCOUNT_TOKEN_ACCESS_TOKEN and must 388 // be empty otherwise. 389 repeated string oauth_scope = 4; 390 391 // An audience the ID token should have. 392 // 393 // Must be set if token_kind is SERVICE_ACCOUNT_TOKEN_ID_TOKEN and must 394 // be empty otherwise. 395 string id_token_audience = 5; 396 397 // Minimally accepted validity duration of the returned token (seconds). 398 // 399 // The server may return a token that lives longer than this. The maximum is 400 // 1h. An attempt to get a token that lives longer than 1h will result in 401 // an error. 402 // 403 // Default is 300 sec. 404 int64 min_validity_duration = 6; 405 406 // Arbitrary key:value pairs describing circumstances of this call. 407 // 408 // Used only for logging and auditing purposes. Not involved in authorization. 409 repeated string audit_tags = 7; 410 } 411 412 413 // MintServiceAccountTokenResponse is returned by MintServiceAccountToken. 414 message MintServiceAccountTokenResponse { 415 string token = 1; // the produced token 416 google.protobuf.Timestamp expiry = 2; // when this token expires 417 418 // Identifier of the service and its version that produced the token. 419 // 420 // Has the form "<app-id>/<module-version>". Used only for logging and 421 // monitoring. 422 string service_version = 3; 423 }