go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/tokenserver/appengine/impl/projectscope/bigquery_log.go (about) 1 // Copyright 2019 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package projectscope 16 17 import ( 18 "context" 19 "net" 20 21 "google.golang.org/protobuf/types/known/timestamppb" 22 23 "go.chromium.org/luci/auth/identity" 24 25 bqpb "go.chromium.org/luci/tokenserver/api/bq" 26 "go.chromium.org/luci/tokenserver/api/minter/v1" 27 "go.chromium.org/luci/tokenserver/appengine/impl/utils" 28 "go.chromium.org/luci/tokenserver/appengine/impl/utils/bq" 29 ) 30 31 func init() { 32 bq.RegisterTokenKind("project_tokens", (*bqpb.ProjectToken)(nil)) 33 } 34 35 // MintedTokenInfo is passed to LogToken. 36 // 37 // It carries all information about the token minting operation and the produced 38 // token. 39 type MintedTokenInfo struct { 40 Request *minter.MintProjectTokenRequest // RPC input, as is 41 Response *minter.MintProjectTokenResponse // RPC output, as is 42 RequestedAt *timestamppb.Timestamp 43 Expiration *timestamppb.Timestamp 44 PeerIdentity identity.Identity // caller identity 45 PeerIP net.IP // caller IP address 46 RequestID string // GAE request ID that handled the RPC 47 AuthDBRev int64 // revision of groups database (or 0 if unknown) 48 } 49 50 // toBigQueryMessage returns a message to upload to BigQuery. 51 func (i *MintedTokenInfo) toBigQueryMessage() *bqpb.ProjectToken { 52 return &bqpb.ProjectToken{ 53 // Information about the produced token. 54 Fingerprint: utils.TokenFingerprint(i.Response.AccessToken), 55 ServiceAccount: i.Response.ServiceAccountEmail, 56 OauthScopes: i.Request.OauthScope, 57 LuciProject: i.Request.LuciProject, 58 ServiceIdentity: i.PeerIdentity.Email(), 59 RequestedAt: i.RequestedAt, 60 Expiration: i.Expiration, 61 AuditTags: i.Request.AuditTags, 62 PeerIp: i.PeerIP.String(), 63 ServiceVersion: i.Response.ServiceVersion, 64 GaeRequestId: i.RequestID, 65 AuthDbRev: i.AuthDBRev, 66 } 67 } 68 69 // TokenLogger records info about the token to BigQuery. 70 type TokenLogger func(context.Context, *MintedTokenInfo) error 71 72 // NewTokenLogger returns a callback that records info about tokens to BigQuery. 73 // 74 // Tokens themselves are not logged. Only first 16 bytes of their SHA256 hashes 75 // (aka 'fingerprint') are. They are used only to identify tokens in logs. 76 // 77 // When dryRun is true, logs to the local text log only, not to BigQuery 78 // (to avoid accidentally pushing fake data to real BigQuery dataset). 79 func NewTokenLogger(dryRun bool) TokenLogger { 80 return func(ctx context.Context, i *MintedTokenInfo) error { 81 return bq.LogToken(ctx, i.toBigQueryMessage(), dryRun) 82 } 83 }