/*
 *
 * Copyright 2014 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

// Package credentials implements various credentials supported by gRPC library, // which encapsulate all the state needed by a client to authenticate with a // server and make various assertions, e.g., about the client's identity, role, // or whether it is authorized to make a particular call.
package credentials // import "google.golang.org/grpc/credentials" import ( icredentials ) // PerRPCCredentials defines the common interface for the credentials which need to // attach security information to every RPC (e.g., oauth2). type PerRPCCredentials interface { // GetRequestMetadata gets the current request metadata, refreshing tokens // if required. This should be called by the transport layer on each // request, and the data should be populated in headers or other // context. If a status code is returned, it will be used as the status for // the RPC (restricted to an allowable set of codes as defined by gRFC // A54). uri is the URI of the entry point for the request. When supported // by the underlying implementation, ctx can be used for timeout and // cancellation. Additionally, RequestInfo data will be available via ctx // to this call. TODO(zhaoq): Define the set of the qualified keys instead // of leaving it as an arbitrary string. GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) // RequireTransportSecurity indicates whether the credentials requires // transport security. RequireTransportSecurity() bool } // SecurityLevel defines the protection level on an established connection. // // This API is experimental. type SecurityLevel int const ( // InvalidSecurityLevel indicates an invalid security level. // The zero SecurityLevel value is invalid for backward compatibility. InvalidSecurityLevel SecurityLevel = iota // NoSecurity indicates a connection is insecure. NoSecurity // IntegrityOnly indicates a connection only provides integrity protection. IntegrityOnly // PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection. PrivacyAndIntegrity ) // String returns SecurityLevel in a string format. func ( SecurityLevel) () string { switch { case NoSecurity: return "NoSecurity" case IntegrityOnly: return "IntegrityOnly" case PrivacyAndIntegrity: return "PrivacyAndIntegrity" } return fmt.Sprintf("invalid SecurityLevel: %v", int()) } // CommonAuthInfo contains authenticated information common to AuthInfo implementations. // It should be embedded in a struct implementing AuthInfo to provide additional information // about the credentials. // // This API is experimental. type CommonAuthInfo struct { SecurityLevel SecurityLevel } // GetCommonAuthInfo returns the pointer to CommonAuthInfo struct. func ( CommonAuthInfo) () CommonAuthInfo { return } // ProtocolInfo provides static information regarding transport credentials. type ProtocolInfo struct { // ProtocolVersion is the gRPC wire protocol version. // // Deprecated: this is unused by gRPC. ProtocolVersion string // SecurityProtocol is the security protocol in use. SecurityProtocol string // SecurityVersion is the security protocol version. It is a static version string from the // credentials, not a value that reflects per-connection protocol negotiation. To retrieve // details about the credentials used for a connection, use the Peer's AuthInfo field instead. // // Deprecated: please use Peer.AuthInfo. SecurityVersion string // ServerName is the user-configured server name. If set, this overrides // the default :authority header used for all RPCs on the channel using the // containing credentials, unless grpc.WithAuthority is set on the channel, // in which case that setting will take precedence. // // This must be a valid `:authority` header according to // [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2). // // Deprecated: Users should use grpc.WithAuthority to override the authority // on a channel instead of configuring the credentials. ServerName string } // AuthInfo defines the common interface for the auth information the users are interested in. // A struct that implements AuthInfo should embed CommonAuthInfo by including additional // information about the credentials in it. type AuthInfo interface { AuthType() string } // AuthorityValidator validates the authority used to override the `:authority` // header. This is an optional interface that implementations of AuthInfo can // implement if they support per-RPC authority overrides. It is invoked when the // application attempts to override the HTTP/2 `:authority` header using the // CallAuthority call option. type AuthorityValidator interface { // ValidateAuthority checks the authority value used to override the // `:authority` header. The authority parameter is the override value // provided by the application via the CallAuthority option. This value // typically corresponds to the server hostname or endpoint the RPC is // targeting. It returns non-nil error if the validation fails. ValidateAuthority(authority string) error } // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC // and the caller should not close rawConn. var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC") // TransportCredentials defines the common interface for all the live gRPC wire // protocols and supported transport security protocols (e.g., TLS, SSL). type TransportCredentials interface { // ClientHandshake does the authentication handshake specified by the // corresponding authentication protocol on rawConn for clients. It returns // the authenticated connection and the corresponding auth information // about the connection. The auth information should embed CommonAuthInfo // to return additional information about the credentials. Implementations // must use the provided context to implement timely cancellation. gRPC // will try to reconnect if the error returned is a temporary error // (io.EOF, context.DeadlineExceeded or err.Temporary() == true). If the // returned error is a wrapper error, implementations should make sure that // the error implements Temporary() to have the correct retry behaviors. // Additionally, ClientHandshakeInfo data will be available via the context // passed to this call. // // The second argument to this method is the `:authority` header value used // while creating new streams on this connection after authentication // succeeds. Implementations must use this as the server name during the // authentication handshake. // // If the returned net.Conn is closed, it MUST close the net.Conn provided. ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error) // ServerHandshake does the authentication handshake for servers. It returns // the authenticated connection and the corresponding auth information about // the connection. The auth information should embed CommonAuthInfo to return additional information // about the credentials. // // If the returned net.Conn is closed, it MUST close the net.Conn provided. ServerHandshake(net.Conn) (net.Conn, AuthInfo, error) // Info provides the ProtocolInfo of this TransportCredentials. Info() ProtocolInfo // Clone makes a copy of this TransportCredentials. Clone() TransportCredentials // OverrideServerName specifies the value used for the following: // // - verifying the hostname on the returned certificates // - as SNI in the client's handshake to support virtual hosting // - as the value for `:authority` header at stream creation time // // The provided string should be a valid `:authority` header according to // [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2). // // Deprecated: this method is unused by gRPC. Users should use // grpc.WithAuthority to override the authority on a channel instead of // configuring the credentials. OverrideServerName(string) error } // Bundle is a combination of TransportCredentials and PerRPCCredentials. // // It also contains a mode switching method, so it can be used as a combination // of different credential policies. // // Bundle cannot be used together with individual TransportCredentials. // PerRPCCredentials from Bundle will be appended to other PerRPCCredentials. // // This API is experimental. type Bundle interface { // TransportCredentials returns the transport credentials from the Bundle. // // Implementations must return non-nil transport credentials. If transport // security is not needed by the Bundle, implementations may choose to // return insecure.NewCredentials(). TransportCredentials() TransportCredentials // PerRPCCredentials returns the per-RPC credentials from the Bundle. // // May be nil if per-RPC credentials are not needed. PerRPCCredentials() PerRPCCredentials // NewWithMode should make a copy of Bundle, and switch mode. Modifying the // existing Bundle may cause races. // // NewWithMode returns nil if the requested mode is not supported. NewWithMode(mode string) (Bundle, error) } // RequestInfo contains request data attached to the context passed to GetRequestMetadata calls. // // This API is experimental. type RequestInfo struct { // The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method") Method string // AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake) AuthInfo AuthInfo } // requestInfoKey is a struct to be used as the key to store RequestInfo in a // context. type requestInfoKey struct{} // RequestInfoFromContext extracts the RequestInfo from the context if it exists. // // This API is experimental. func ( context.Context) ( RequestInfo, bool) { , = .Value(requestInfoKey{}).(RequestInfo) return , } // NewContextWithRequestInfo creates a new context from ctx and attaches ri to it. // // This RequestInfo will be accessible via RequestInfoFromContext. // // Intended to be used from tests for PerRPCCredentials implementations (that // often need to check connection's SecurityLevel). Should not be used from // non-test code: the gRPC client already prepares a context with the correct // RequestInfo attached when calling PerRPCCredentials.GetRequestMetadata. // // This API is experimental. func ( context.Context, RequestInfo) context.Context { return context.WithValue(, requestInfoKey{}, ) } // ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes // it possible to pass arbitrary data to the handshaker from gRPC, resolver, // balancer etc. Individual credential implementations control the actual // format of the data that they are willing to receive. // // This API is experimental. type ClientHandshakeInfo struct { // Attributes contains the attributes for the address. It could be provided // by the gRPC, resolver, balancer etc. Attributes *attributes.Attributes } // ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored // in ctx. // // This API is experimental. func ( context.Context) ClientHandshakeInfo { , := icredentials.ClientHandshakeInfoFromContext().(ClientHandshakeInfo) return } // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one. // It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility. // // This API is experimental. func ( AuthInfo, SecurityLevel) error { type interface { () CommonAuthInfo } if == nil { return errors.New("AuthInfo is nil") } if , := .(); { // CommonAuthInfo.SecurityLevel has an invalid value. if .().SecurityLevel == InvalidSecurityLevel { return nil } if .().SecurityLevel < { return fmt.Errorf("requires SecurityLevel %v; connection has %v", , .().SecurityLevel) } } // The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method. return nil } // ChannelzSecurityInfo defines the interface that security protocols should implement // in order to provide security info to channelz. // // This API is experimental. type ChannelzSecurityInfo interface { GetSecurityValue() ChannelzSecurityValue } // ChannelzSecurityValue defines the interface that GetSecurityValue() return value // should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue // and *OtherChannelzSecurityValue. // // This API is experimental. type ChannelzSecurityValue interface { isChannelzSecurityValue() } // OtherChannelzSecurityValue defines the struct that non-TLS protocol should return // from GetSecurityValue(), which contains protocol specific security info. Note // the Value field will be sent to users of channelz requesting channel info, and // thus sensitive info should better be avoided. // // This API is experimental. type OtherChannelzSecurityValue struct { ChannelzSecurityValue Name string Value proto.Message }