go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/tokenserver/appengine/impl/machinetoken/bigquery_log.go (about) 1 // Copyright 2017 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 machinetoken 16 17 import ( 18 "context" 19 "math/big" 20 "net" 21 22 "google.golang.org/protobuf/types/known/timestamppb" 23 24 tokenserver "go.chromium.org/luci/tokenserver/api" 25 bqpb "go.chromium.org/luci/tokenserver/api/bq" 26 "go.chromium.org/luci/tokenserver/api/minter/v1" 27 28 "go.chromium.org/luci/tokenserver/appengine/impl/certconfig" 29 "go.chromium.org/luci/tokenserver/appengine/impl/utils" 30 "go.chromium.org/luci/tokenserver/appengine/impl/utils/bq" 31 ) 32 33 func init() { 34 bq.RegisterTokenKind("machine_tokens", (*bqpb.MachineToken)(nil)) 35 } 36 37 // MintedTokenInfo is passed to LogToken. 38 // 39 // It carries all information about the token minting operation and the produced 40 // token. 41 type MintedTokenInfo struct { 42 Request *minter.MachineTokenRequest // the token request, as presented by the client 43 Response *minter.MachineTokenResponse // the response, as returned by the minter 44 TokenBody *tokenserver.MachineTokenBody // deserialized token (same as in Response) 45 CA *certconfig.CA // CA configuration used to authorize this request 46 PeerIP net.IP // caller IP address 47 RequestID string // GAE request ID that handled the RPC 48 } 49 50 // toBigQueryMessage returns a message to upload to BigQuery. 51 func (i *MintedTokenInfo) toBigQueryMessage() *bqpb.MachineToken { 52 // LUCI_MACHINE_TOKEN is the only supported type currently. 53 if i.Request.TokenType != tokenserver.MachineTokenType_LUCI_MACHINE_TOKEN { 54 panic("unknown token type") 55 } 56 return &bqpb.MachineToken{ 57 // Identifier of the token body. 58 Fingerprint: utils.TokenFingerprint(i.Response.GetLuciMachineToken().MachineToken), 59 60 // Information about the token. 61 MachineFqdn: i.TokenBody.MachineFqdn, 62 TokenType: i.Request.TokenType, 63 IssuedAt: ×tamppb.Timestamp{Seconds: int64(i.TokenBody.IssuedAt)}, 64 Expiration: ×tamppb.Timestamp{Seconds: int64(i.TokenBody.IssuedAt + i.TokenBody.Lifetime)}, 65 CertSerialNumber: new(big.Int).SetBytes(i.TokenBody.CertSn).String(), 66 SignatureAlgorithm: i.Request.SignatureAlgorithm, 67 68 // Information about the CA used to authorize this request. 69 CaCommonName: i.CA.CN, 70 CaConfigRev: i.CA.UpdatedRev, 71 72 // Information about the request handler. 73 PeerIp: i.PeerIP.String(), 74 ServiceVersion: i.Response.ServiceVersion, 75 GaeRequestId: i.RequestID, 76 } 77 } 78 79 // TokenLogger records info about the token to BigQuery. 80 type TokenLogger func(context.Context, *MintedTokenInfo) error 81 82 // NewTokenLogger returns a callback that records info about tokens to BigQuery. 83 // 84 // Tokens themselves are not logged. Only first 16 bytes of their SHA256 hashes 85 // (aka 'fingerprint') are. They are used only to identify tokens in logs. 86 // 87 // When dryRun is true, logs to the local text log only, not to BigQuery 88 // (to avoid accidentally pushing fake data to real BigQuery dataset). 89 func NewTokenLogger(dryRun bool) TokenLogger { 90 return func(ctx context.Context, i *MintedTokenInfo) error { 91 return bq.LogToken(ctx, i.toBigQueryMessage(), dryRun) 92 } 93 }