go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/tokenserver/appengine/impl/serviceaccounts/bigquery_log.go (about)

     1  // Copyright 2020 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 serviceaccounts
    16  
    17  import (
    18  	"context"
    19  	"net"
    20  	"time"
    21  
    22  	"google.golang.org/protobuf/types/known/timestamppb"
    23  
    24  	"go.chromium.org/luci/auth/identity"
    25  
    26  	bqpb "go.chromium.org/luci/tokenserver/api/bq"
    27  	"go.chromium.org/luci/tokenserver/api/minter/v1"
    28  	"go.chromium.org/luci/tokenserver/appengine/impl/utils"
    29  	"go.chromium.org/luci/tokenserver/appengine/impl/utils/bq"
    30  )
    31  
    32  func init() {
    33  	bq.RegisterTokenKind("service_account_tokens", (*bqpb.ServiceAccountToken)(nil))
    34  }
    35  
    36  // MintedTokenInfo is passed to LogToken.
    37  //
    38  // It carries all information about the token minting operation and the produced
    39  // token.
    40  type MintedTokenInfo struct {
    41  	Request         *minter.MintServiceAccountTokenRequest  // RPC input, as is
    42  	Response        *minter.MintServiceAccountTokenResponse // RPC output, as is
    43  	RequestedAt     time.Time
    44  	OAuthScopes     []string          // normalized list of requested OAuth scopes
    45  	RequestIdentity identity.Identity // identity used in authorization
    46  	PeerIdentity    identity.Identity // identity of the direct peer
    47  	ConfigRev       string            // revision of the service config
    48  	PeerIP          net.IP            // caller's IP
    49  	RequestID       string            // GAE request ID that handles the RPC
    50  	AuthDBRev       int64             // revision of the authorization database
    51  }
    52  
    53  // toBigQueryMessage returns a message to upload to BigQuery.
    54  func (i *MintedTokenInfo) toBigQueryMessage() *bqpb.ServiceAccountToken {
    55  	return &bqpb.ServiceAccountToken{
    56  		Fingerprint:     utils.TokenFingerprint(i.Response.Token),
    57  		Kind:            i.Request.TokenKind,
    58  		ServiceAccount:  i.Request.ServiceAccount,
    59  		Realm:           i.Request.Realm,
    60  		OauthScopes:     i.OAuthScopes,
    61  		IdTokenAudience: i.Request.IdTokenAudience,
    62  		RequestIdentity: string(i.RequestIdentity),
    63  		PeerIdentity:    string(i.PeerIdentity),
    64  		RequestedAt:     timestamppb.New(i.RequestedAt),
    65  		Expiration:      i.Response.Expiry,
    66  		AuditTags:       i.Request.AuditTags,
    67  		ConfigRev:       i.ConfigRev,
    68  		PeerIp:          i.PeerIP.String(),
    69  		ServiceVersion:  i.Response.ServiceVersion,
    70  		GaeRequestId:    i.RequestID,
    71  		AuthDbRev:       i.AuthDBRev,
    72  	}
    73  }
    74  
    75  // TokenLogger records info about the token to BigQuery.
    76  type TokenLogger func(context.Context, *MintedTokenInfo) error
    77  
    78  // NewTokenLogger returns a callback that records info about tokens to BigQuery.
    79  //
    80  // Tokens themselves are not logged. Only first 16 bytes of their SHA256 hashes
    81  // (aka 'fingerprint') are. They are used only to identify tokens in logs.
    82  //
    83  // When dryRun is true, logs to the local text log only, not to BigQuery
    84  // (to avoid accidentally pushing fake data to real BigQuery dataset).
    85  func NewTokenLogger(dryRun bool) TokenLogger {
    86  	return func(ctx context.Context, i *MintedTokenInfo) error {
    87  		return bq.LogToken(ctx, i.toBigQueryMessage(), dryRun)
    88  	}
    89  }