istio.io/istio@v0.0.0-20240520182934-d79c90f27776/security/pkg/nodeagent/caclient/credentials.go (about) 1 // Copyright Istio 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 caclient 16 17 import ( 18 "context" 19 "fmt" 20 21 "google.golang.org/grpc/credentials" 22 23 "istio.io/istio/pkg/security" 24 ) 25 26 // TokenProvider is a grpc PerRPCCredentials that can be used to attach a JWT token to each gRPC call. 27 // TokenProvider can be used for XDS, which may involve token exchange through STS. 28 type DefaultTokenProvider struct { 29 opts *security.Options 30 } 31 32 var _ credentials.PerRPCCredentials = &DefaultTokenProvider{} 33 34 func NewDefaultTokenProvider(opts *security.Options) credentials.PerRPCCredentials { 35 return &DefaultTokenProvider{opts} 36 } 37 38 func (t *DefaultTokenProvider) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { 39 if t == nil { 40 return nil, nil 41 } 42 token, err := t.GetToken() 43 if err != nil { 44 return nil, err 45 } 46 if token == "" { 47 return nil, nil 48 } 49 return map[string]string{ 50 "authorization": "Bearer " + token, 51 }, nil 52 } 53 54 // Allow the token provider to be used regardless of transport security; callers can determine whether 55 // this is safe themselves. 56 func (t *DefaultTokenProvider) RequireTransportSecurity() bool { 57 return false 58 } 59 60 // GetToken fetches a token to attach to a request. Returning "", nil will cause no header to be 61 // added; while a non-nil error will block the request If the token selected is not found, no error 62 // will be returned, causing no authorization header to be set. This ensures that even if the JWT 63 // token is missing (for example, on a VM that has rebooted, causing the token to be removed from 64 // volatile memory), we can still proceed and allow other authentication methods to potentially 65 // handle the request, such as mTLS. 66 func (t *DefaultTokenProvider) GetToken() (string, error) { 67 if t.opts.CredFetcher == nil { 68 return "", nil 69 } 70 token, err := t.opts.CredFetcher.GetPlatformCredential() 71 if err != nil { 72 return "", fmt.Errorf("fetch platform credential: %v", err) 73 } 74 75 return token, nil 76 }