Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 syntax = "proto3"; | 5 syntax = "proto3"; |
| 6 | 6 |
| 7 package tokenserver.minter; | 7 package tokenserver.minter; |
| 8 | 8 |
| 9 import "google/protobuf/timestamp.proto"; | 9 import "google/protobuf/timestamp.proto"; |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 BAD_CERTIFICATE_FORMAT = 4; // malformed or unsupported certificate | 30 BAD_CERTIFICATE_FORMAT = 4; // malformed or unsupported certificate |
| 31 BAD_SIGNATURE = 5; // signature doesn't match or can't be verifi ed | 31 BAD_SIGNATURE = 5; // signature doesn't match or can't be verifi ed |
| 32 UNTRUSTED_CERTIFICATE = 6; // invalid certificate or can't verify it yet | 32 UNTRUSTED_CERTIFICATE = 6; // invalid certificate or can't verify it yet |
| 33 BAD_TOKEN_ARGUMENTS = 7; // FQDN or Scopes are invalid or not whitelis ted | 33 BAD_TOKEN_ARGUMENTS = 7; // FQDN or Scopes are invalid or not whitelis ted |
| 34 MACHINE_TOKEN_MINTING_ERROR = 8; // unspecified fatal error when minting a mac hine token | 34 MACHINE_TOKEN_MINTING_ERROR = 8; // unspecified fatal error when minting a mac hine token |
| 35 } | 35 } |
| 36 | 36 |
| 37 | 37 |
| 38 // TokenMinter implements main API of the token server. | 38 // TokenMinter implements main API of the token server. |
| 39 // | 39 // |
| 40 // It provides an interface for generating and inspecting of: | 40 // It provides an interface for generating: |
| 41 // | 41 // |
| 42 // * Machine tokens: short lived stateless tokens used in Swarming bot | 42 // * Machine tokens: short lived stateless tokens used in Swarming bot |
| 43 // authentication protocol. They are derived from PKI keys deployed on bots, | 43 // authentication protocol. They are derived from PKI keys deployed on bots, |
| 44 // and consumed primarily by Swarming. | 44 // and consumed primarily by Swarming. See MintMachineToken. |
| 45 // | 45 // |
| 46 // * Delegation tokens: these are involved whenever something wants to act on | 46 // * Delegation tokens: these are involved whenever a service calls other |
| 47 // behalf of something else. In particular, whenever a service calls other | 47 // service on behalf of a user. They are passed via 'X-Delegation-Token-V1' |
| 48 // service on behalf of a user, or when a user posts a Swarming task that | 48 // HTTP header along with a credentials of the impersonating user. |
| 49 // runs in a context of some service account. There are multiple kinds of | 49 // See MintDelegationToken. |
| 50 // delegation tokens: | |
| 51 // - Bearer delegation tokens: they passed via 'X-Delegation-Token-V1' | |
| 52 // HTTP header and can be used to "impersonate" the identity of a caller. | |
| 53 // - OAuth2 token grants: they are signed assertions that particular | |
| 54 // services are allowed to grab service account OAuth2 tokens. They are | |
| 55 // used in Swarming service accounts implementation. This is TODO. | |
| 56 // | 50 // |
| 57 // * OAuth2 tokens: these are regular Google OAuth2 access tokens associated | 51 // * OAuth2 token grants: they are signed assertions that particular |
| 58 // with various service accounts (that the token server has | 52 // services are allowed to grab service account OAuth2 tokens on behalf |
| 59 // serviceAccountActor role in). This is TODO. | 53 // of particular end users. They are used in Swarming service accounts |
| 54 // implementation. See MintOAuthTokenGrant and MintOAuthTokenViaGrant. | |
| 55 // | |
| 56 // * OAuth2 access tokens: these are regular Google OAuth2 access tokens | |
|
smut
2017/07/28 23:07:37
Is "Google OAuth2" actually different than "OAuth2
Vadim Sh.
2017/07/28 23:11:09
Yeah, only Google servers accept them :) Support f
| |
| 57 // associated with various service accounts. See MintOAuthTokenGrant | |
| 58 // and MintOAuthTokenViaGrant. | |
| 60 service TokenMinter { | 59 service TokenMinter { |
| 61 // MintMachineToken generates a new token for an authenticated machine. | 60 // MintMachineToken generates a new token for an authenticated machine. |
| 62 // | 61 // |
| 63 // It checks that provided certificate was signed by some trusted CA, and it | 62 // It checks that provided certificate was signed by some trusted CA, and it |
| 64 // is still valid (non-expired and hasn't been revoked). It then checks that | 63 // is still valid (non-expired and hasn't been revoked). It then checks that |
| 65 // the request was signed by the corresponding private key. Finally it checks | 64 // the request was signed by the corresponding private key. Finally it checks |
| 66 // that the caller is authorized to generate requested kind of token. | 65 // that the caller is authorized to generate requested kind of token. |
| 67 // | 66 // |
| 68 // If everything checks out, it generates and returns a new machine token. | 67 // If everything checks out, it generates and returns a new machine token. |
| 69 // | 68 // |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 82 // the token): | 81 // the token): |
| 83 // * They have expiration time. | 82 // * They have expiration time. |
| 84 // * They are usable only if presented with a credential of someone from | 83 // * They are usable only if presented with a credential of someone from |
| 85 // the 'audience' list. | 84 // the 'audience' list. |
| 86 // * They are usable only on services specified in the 'services' list. | 85 // * They are usable only on services specified in the 'services' list. |
| 87 // | 86 // |
| 88 // The token server must be configured in advance with all expected | 87 // The token server must be configured in advance with all expected |
| 89 // combinations of (caller identity, delegated identity, audience, service) | 88 // combinations of (caller identity, delegated identity, audience, service) |
| 90 // tuples. See DelegationRule in config.proto. | 89 // tuples. See DelegationRule in config.proto. |
| 91 rpc MintDelegationToken(MintDelegationTokenRequest) returns (MintDelegationTok enResponse); | 90 rpc MintDelegationToken(MintDelegationTokenRequest) returns (MintDelegationTok enResponse); |
| 91 | |
| 92 // MintOAuthTokenGrant generates a new grant for getting an OAuth2 token. | |
| 93 // | |
| 94 // This is a special (opaque for clients) token that asserts that the caller | |
| 95 // at the time of the call was allowed to act as a particular service account | |
| 96 // to perform a task authorized by an end-user. | |
| 97 // | |
| 98 // The returned grant can be used later (when the end-user is no longer | |
| 99 // present) to get a real OAuth2 access token via MintOAuthTokenViaGrant call. | |
| 100 // | |
| 101 // This pair of RPCs is used to "delay" generation of service account OAuth | |
| 102 // token until some later time, when it is actually needed. This is used by | |
| 103 // Swarming: | |
| 104 // 1. When the task is posted, Swarming calls MintOAuthTokenGrant to verify | |
| 105 // that the end-user is allowed to act as the requested service account | |
| 106 // on Swarming. On success, Swarming stores the grant in the task | |
| 107 // metadata. | |
| 108 // 2. At a later time, when the task is executing and it needs an access | |
| 109 // token, Swarming calls MintOAuthTokenViaGrant to convert the grant into | |
| 110 // a real OAuth2 token. | |
| 111 // | |
| 112 // The returned grant can be used multiple times (as long as its validity | |
| 113 // duration and the token server policy allows). | |
| 114 // | |
| 115 // The token server must be configured in advance with all expected | |
| 116 // combinations of (caller identity, service account name, end users) tuples. | |
| 117 // See ServiceAccountRule in config.proto. | |
| 118 // | |
| 119 // MintOAuthTokenGrant will check that the requested usage is allowed by the | |
| 120 // rules. Later, MintOAuthTokenViaGrant will recheck this too. | |
| 121 rpc MintOAuthTokenGrant(MintOAuthTokenGrantRequest) returns (MintOAuthTokenGra ntResponse); | |
| 122 | |
| 123 // MintOAuthTokenViaGrant converts an OAuth2 token grant into an access token. | |
| 124 // | |
| 125 // The grant must be previously generated by MintOAuthTokenGrant function, see | |
| 126 // its docs for more details. | |
| 127 rpc MintOAuthTokenViaGrant(MintOAuthTokenViaGrantRequest) returns (MintOAuthTo kenViaGrantResponse); | |
| 92 } | 128 } |
| 93 | 129 |
| 94 | 130 |
| 95 //////////////////////////////////////////////////////////////////////////////// | 131 //////////////////////////////////////////////////////////////////////////////// |
| 96 // Machine Tokens messages | 132 // Machine tokens. |
| 97 | 133 |
| 98 | 134 |
| 99 // MintMachineTokenRequest wraps a serialized and signed MachineTokenRequest | 135 // MintMachineTokenRequest wraps a serialized and signed MachineTokenRequest |
| 100 // message. | 136 // message. |
| 101 message MintMachineTokenRequest { | 137 message MintMachineTokenRequest { |
| 102 // The protobuf-serialized MachineTokenRequest message, signed by the private | 138 // The protobuf-serialized MachineTokenRequest message, signed by the private |
| 103 // key that matches MachineTokenRequest.certificate. | 139 // key that matches MachineTokenRequest.certificate. |
| 104 // | 140 // |
| 105 // We have to send it as a byte blob to avoid dealing with possible protobuf | 141 // We have to send it as a byte blob to avoid dealing with possible protobuf |
| 106 // serialization inconsistencies when checking the signature. | 142 // serialization inconsistencies when checking the signature. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 131 // Timestamp when this request was created, by the issuer clock. | 167 // Timestamp when this request was created, by the issuer clock. |
| 132 google.protobuf.Timestamp issued_at = 3; | 168 google.protobuf.Timestamp issued_at = 3; |
| 133 | 169 |
| 134 // The token type being requested. | 170 // The token type being requested. |
| 135 // | 171 // |
| 136 // Defines what fields of the response are set. | 172 // Defines what fields of the response are set. |
| 137 MachineTokenType token_type = 4; | 173 MachineTokenType token_type = 4; |
| 138 } | 174 } |
| 139 | 175 |
| 140 | 176 |
| 141 // MintMachineTokenResponse is returned by 'MintMachineToken' if the server | 177 // MintMachineTokenResponse is returned by MintMachineToken if the server |
| 142 // processed the request. | 178 // processed the request. |
| 143 // | 179 // |
| 144 // It's returned even if server refuses to mint a token. It contains the error | 180 // It's returned even if server refuses to mint a token. It contains the error |
| 145 // details in that case. | 181 // details in that case. |
| 146 message MintMachineTokenResponse { | 182 message MintMachineTokenResponse { |
| 147 // Possible kinds of fatal errors. | 183 // Possible kinds of fatal errors. |
| 148 // | 184 // |
| 149 // Non fatal errors are returned as grpc.Internal errors instead. | 185 // Non fatal errors are returned as grpc.Internal errors instead. |
| 150 ErrorCode error_code = 1; | 186 ErrorCode error_code = 1; |
| 151 | 187 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 // The token here is supposed to be treated as an opaque base64-encoded blob, | 230 // The token here is supposed to be treated as an opaque base64-encoded blob, |
| 195 // but in reality it is serialized MachineTokenEnvelope, see machine_token.proto | 231 // but in reality it is serialized MachineTokenEnvelope, see machine_token.proto |
| 196 // and read the comment there for more info about the token format. | 232 // and read the comment there for more info about the token format. |
| 197 message LuciMachineToken { | 233 message LuciMachineToken { |
| 198 string machine_token = 1; // the actual token | 234 string machine_token = 1; // the actual token |
| 199 google.protobuf.Timestamp expiry = 2; // when the token expires | 235 google.protobuf.Timestamp expiry = 2; // when the token expires |
| 200 } | 236 } |
| 201 | 237 |
| 202 | 238 |
| 203 //////////////////////////////////////////////////////////////////////////////// | 239 //////////////////////////////////////////////////////////////////////////////// |
| 204 // Delegation Tokens messages | 240 // Delegation tokens. |
| 205 | 241 |
| 206 | 242 |
| 207 // MintDelegationTokenRequest is passed to MintDelegationToken. | 243 // MintDelegationTokenRequest is passed to MintDelegationToken. |
| 208 message MintDelegationTokenRequest { | 244 message MintDelegationTokenRequest { |
| 209 // Identity whose authority is delegated. | 245 // Identity whose authority is delegated. |
| 210 // | 246 // |
| 211 // A string of the form "user:<email>" or a special token "REQUESTOR" that | 247 // A string of the form "user:<email>" or a special token "REQUESTOR" that |
| 212 // means to delegate caller's own identity. The token server will check its | 248 // means to delegate caller's own identity. The token server will check its |
| 213 // ACLs to make sure the caller is authorized to impersonate this identity. | 249 // ACLs to make sure the caller is authorized to impersonate this identity. |
| 214 // | 250 // |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 245 repeated string services = 4; | 281 repeated string services = 4; |
| 246 | 282 |
| 247 // Optional reason why the token is created. | 283 // Optional reason why the token is created. |
| 248 // | 284 // |
| 249 // Used only for logging and auditing purposes. Doesn't become part of the | 285 // Used only for logging and auditing purposes. Doesn't become part of the |
| 250 // token. | 286 // token. |
| 251 string intent = 5; | 287 string intent = 5; |
| 252 } | 288 } |
| 253 | 289 |
| 254 | 290 |
| 255 // MintDelegationTokenResponse is returned by 'MintDelegationToken' on success. | 291 // MintDelegationTokenResponse is returned by MintDelegationToken on success. |
| 256 // | 292 // |
| 257 // Errors are returned via standard gRPC codes. | 293 // Errors are returned via standard gRPC codes. |
| 258 message MintDelegationTokenResponse { | 294 message MintDelegationTokenResponse { |
| 259 // The actual base64-encoded signed token. | 295 // The actual base64-encoded signed token. |
| 260 string token = 1; | 296 string token = 1; |
| 261 | 297 |
| 262 // Same data as in 'token' in deserialized form, just for convenience. | 298 // Same data as in 'token' in deserialized form, just for convenience. |
| 263 // | 299 // |
| 264 // Mostly for JSON encoding users, since they may not understand proto-encoded | 300 // Mostly for JSON encoding users, since they may not understand proto-encoded |
| 265 // tokens. | 301 // tokens. |
| 266 messages.Subtoken delegation_subtoken = 2; | 302 messages.Subtoken delegation_subtoken = 2; |
| 267 | 303 |
| 268 // Identifier of the service and its version that produced the token. | 304 // Identifier of the service and its version that produced the token. |
| 269 // | 305 // |
| 270 // Has the form "<app-id>/<module-version>". This is _not_ part of the token. | 306 // Has the form "<app-id>/<module-version>". This is _not_ part of the token. |
| 307 // Used only for logging and monitoring. | |
| 271 string service_version = 3; | 308 string service_version = 3; |
| 272 } | 309 } |
| 310 | |
| 311 | |
| 312 //////////////////////////////////////////////////////////////////////////////// | |
| 313 // OAuth2 access token grants and OAuth2 service account access tokens. | |
| 314 | |
| 315 | |
| 316 // MintOAuthTokenGrantRequest is passed to MintOAuthTokenGrant. | |
| 317 // | |
| 318 // Additional implicit field is the identity of whoever makes this call. It | |
| 319 // becomes 'wielder_identity' of the generated token. | |
| 320 message MintOAuthTokenGrantRequest { | |
| 321 // Service account identity the end user wants to act as. | |
| 322 // | |
| 323 // A string of the form "user:<email>". | |
| 324 // | |
| 325 // Required. | |
| 326 string service_account = 1; | |
| 327 | |
| 328 // How long the generated grant should be considered valid (in seconds). | |
| 329 // | |
| 330 // Default is 3600 sec. | |
| 331 int64 validity_duration = 2; | |
| 332 | |
| 333 // An end user that wants to act as the service account (perhaps indirectly). | |
| 334 // | |
| 335 // A string of the form "user:<email>". On Swarming, this is an identity of | |
| 336 // a user that posted the task. | |
| 337 // | |
| 338 // TODO(vadimsh): Verify that this user is present during MintOAuthTokenGrant | |
| 339 // RPC by requiring the end user's credentials, e.g make Swarming forward | |
| 340 // user's OAuth token to the token server, where it can be validated. | |
| 341 // | |
| 342 // Required. | |
| 343 string end_user_identity = 3; | |
| 344 | |
| 345 // Optional reason why the grant is created. | |
| 346 // | |
| 347 // Used only for logging and auditing purposes. Doesn't become part of the | |
| 348 // grant. | |
| 349 string intent = 4; | |
| 350 } | |
| 351 | |
| 352 | |
| 353 // MintOAuthTokenGrantResponse is returned by MintOAuthTokenGrant. | |
| 354 message MintOAuthTokenGrantResponse { | |
| 355 string grant_token = 1; // an opaque urlsafe token | |
| 356 google.protobuf.Timestamp expiry = 2; // when this token expires | |
| 357 | |
| 358 // Identifier of the service and its version that produced the token. | |
| 359 // | |
| 360 // Has the form "<app-id>/<module-version>". This is _not_ part of the token. | |
| 361 // Used only for logging and monitoring. | |
| 362 string service_version = 3; | |
| 363 } | |
| 364 | |
| 365 | |
| 366 // MintOAuthTokenViaGrantRequest is passed to MintOAuthTokenViaGrant. | |
| 367 // | |
| 368 // Additional implicit field is the identity of whoever makes this call. It is | |
| 369 // compared against 'wielder_identity' inside the token. | |
| 370 message MintOAuthTokenViaGrantRequest { | |
| 371 // A previously generated grant, as returned by MintOAuthTokenGrant. | |
| 372 string grant_token = 1; | |
| 373 | |
| 374 // The list of OAuth scopes the access token should have. | |
| 375 // | |
| 376 // The server may reject the request if some scopes are not allowed. | |
| 377 repeated string oauth_scopes = 2; | |
| 378 | |
| 379 // Minimally accepted validity duration of the returned OAuth token (seconds). | |
| 380 // | |
| 381 // The server may return a token that lives longer than this. The maximum is | |
| 382 // 1h. An attempt to get a token that lives longer than 1h will result in | |
| 383 // an error. | |
| 384 // | |
| 385 // The returned token validity duration doesn't depend on the lifetime of | |
| 386 // the grant: it's possible to use a grant that expires in 1 sec to get an | |
| 387 // access token that lives for 1h. | |
| 388 // | |
| 389 // Default is 300 sec. | |
| 390 int64 min_validity_duration = 3; | |
| 391 } | |
| 392 | |
| 393 | |
| 394 // MintOAuthTokenViaGrantResponse is returned by MintOAuthTokenViaGrant. | |
| 395 message MintOAuthTokenViaGrantResponse { | |
| 396 string access_token = 1; // service account OAuth2 access token | |
| 397 google.protobuf.Timestamp expiry = 2; // when this token expires | |
| 398 | |
| 399 // Identifier of the service and its version that produced the token. | |
| 400 // | |
| 401 // Has the form "<app-id>/<module-version>". Used only for logging and | |
| 402 // monitoring. | |
| 403 string service_version = 3; | |
| 404 } | |
| OLD | NEW |