blob: 06f6c6c70a94272e446ad5473d62f97b9dc69761 [file] [log] [blame]
William Kurkianea869482019-04-09 15:16:11 -04001/*
2 *
3 * Copyright 2014 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19// Package credentials implements various credentials supported by gRPC library,
20// which encapsulate all the state needed by a client to authenticate with a
21// server and make various assertions, e.g., about the client's identity, role,
22// or whether it is authorized to make a particular call.
23package credentials // import "google.golang.org/grpc/credentials"
24
25import (
26 "context"
William Kurkianea869482019-04-09 15:16:11 -040027 "errors"
28 "fmt"
William Kurkianea869482019-04-09 15:16:11 -040029 "net"
William Kurkianea869482019-04-09 15:16:11 -040030
Abhay Kumara61c5222025-11-10 07:32:50 +000031 "google.golang.org/grpc/attributes"
32 icredentials "google.golang.org/grpc/internal/credentials"
33 "google.golang.org/protobuf/proto"
William Kurkianea869482019-04-09 15:16:11 -040034)
35
William Kurkianea869482019-04-09 15:16:11 -040036// PerRPCCredentials defines the common interface for the credentials which need to
37// attach security information to every RPC (e.g., oauth2).
38type PerRPCCredentials interface {
Abhay Kumara61c5222025-11-10 07:32:50 +000039 // GetRequestMetadata gets the current request metadata, refreshing tokens
40 // if required. This should be called by the transport layer on each
41 // request, and the data should be populated in headers or other
42 // context. If a status code is returned, it will be used as the status for
43 // the RPC (restricted to an allowable set of codes as defined by gRFC
44 // A54). uri is the URI of the entry point for the request. When supported
45 // by the underlying implementation, ctx can be used for timeout and
46 // cancellation. Additionally, RequestInfo data will be available via ctx
bseeniva0b9cbcb2026-02-12 19:11:11 +053047 // to this call.
William Kurkianea869482019-04-09 15:16:11 -040048 GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
49 // RequireTransportSecurity indicates whether the credentials requires
50 // transport security.
51 RequireTransportSecurity() bool
52}
53
Abhay Kumara61c5222025-11-10 07:32:50 +000054// SecurityLevel defines the protection level on an established connection.
55//
56// This API is experimental.
57type SecurityLevel int
58
59const (
60 // InvalidSecurityLevel indicates an invalid security level.
61 // The zero SecurityLevel value is invalid for backward compatibility.
62 InvalidSecurityLevel SecurityLevel = iota
63 // NoSecurity indicates a connection is insecure.
64 NoSecurity
65 // IntegrityOnly indicates a connection only provides integrity protection.
66 IntegrityOnly
67 // PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection.
68 PrivacyAndIntegrity
69)
70
71// String returns SecurityLevel in a string format.
72func (s SecurityLevel) String() string {
73 switch s {
74 case NoSecurity:
75 return "NoSecurity"
76 case IntegrityOnly:
77 return "IntegrityOnly"
78 case PrivacyAndIntegrity:
79 return "PrivacyAndIntegrity"
80 }
81 return fmt.Sprintf("invalid SecurityLevel: %v", int(s))
82}
83
84// CommonAuthInfo contains authenticated information common to AuthInfo implementations.
85// It should be embedded in a struct implementing AuthInfo to provide additional information
86// about the credentials.
87//
88// This API is experimental.
89type CommonAuthInfo struct {
90 SecurityLevel SecurityLevel
91}
92
93// GetCommonAuthInfo returns the pointer to CommonAuthInfo struct.
94func (c CommonAuthInfo) GetCommonAuthInfo() CommonAuthInfo {
95 return c
96}
97
98// ProtocolInfo provides static information regarding transport credentials.
William Kurkianea869482019-04-09 15:16:11 -040099type ProtocolInfo struct {
100 // ProtocolVersion is the gRPC wire protocol version.
Abhay Kumara61c5222025-11-10 07:32:50 +0000101 //
102 // Deprecated: this is unused by gRPC.
William Kurkianea869482019-04-09 15:16:11 -0400103 ProtocolVersion string
104 // SecurityProtocol is the security protocol in use.
105 SecurityProtocol string
Abhay Kumara61c5222025-11-10 07:32:50 +0000106 // SecurityVersion is the security protocol version. It is a static version string from the
107 // credentials, not a value that reflects per-connection protocol negotiation. To retrieve
108 // details about the credentials used for a connection, use the Peer's AuthInfo field instead.
109 //
110 // Deprecated: please use Peer.AuthInfo.
William Kurkianea869482019-04-09 15:16:11 -0400111 SecurityVersion string
Abhay Kumara61c5222025-11-10 07:32:50 +0000112 // ServerName is the user-configured server name. If set, this overrides
113 // the default :authority header used for all RPCs on the channel using the
114 // containing credentials, unless grpc.WithAuthority is set on the channel,
115 // in which case that setting will take precedence.
116 //
117 // This must be a valid `:authority` header according to
118 // [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2).
119 //
120 // Deprecated: Users should use grpc.WithAuthority to override the authority
121 // on a channel instead of configuring the credentials.
William Kurkianea869482019-04-09 15:16:11 -0400122 ServerName string
123}
124
125// AuthInfo defines the common interface for the auth information the users are interested in.
Abhay Kumara61c5222025-11-10 07:32:50 +0000126// A struct that implements AuthInfo should embed CommonAuthInfo by including additional
127// information about the credentials in it.
William Kurkianea869482019-04-09 15:16:11 -0400128type AuthInfo interface {
129 AuthType() string
130}
131
Abhay Kumara61c5222025-11-10 07:32:50 +0000132// AuthorityValidator validates the authority used to override the `:authority`
133// header. This is an optional interface that implementations of AuthInfo can
134// implement if they support per-RPC authority overrides. It is invoked when the
135// application attempts to override the HTTP/2 `:authority` header using the
136// CallAuthority call option.
137type AuthorityValidator interface {
138 // ValidateAuthority checks the authority value used to override the
139 // `:authority` header. The authority parameter is the override value
140 // provided by the application via the CallAuthority option. This value
141 // typically corresponds to the server hostname or endpoint the RPC is
142 // targeting. It returns non-nil error if the validation fails.
143 ValidateAuthority(authority string) error
144}
145
William Kurkianea869482019-04-09 15:16:11 -0400146// ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
147// and the caller should not close rawConn.
148var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
149
150// TransportCredentials defines the common interface for all the live gRPC wire
151// protocols and supported transport security protocols (e.g., TLS, SSL).
152type TransportCredentials interface {
Abhay Kumara61c5222025-11-10 07:32:50 +0000153 // ClientHandshake does the authentication handshake specified by the
154 // corresponding authentication protocol on rawConn for clients. It returns
155 // the authenticated connection and the corresponding auth information
156 // about the connection. The auth information should embed CommonAuthInfo
157 // to return additional information about the credentials. Implementations
158 // must use the provided context to implement timely cancellation. gRPC
159 // will try to reconnect if the error returned is a temporary error
160 // (io.EOF, context.DeadlineExceeded or err.Temporary() == true). If the
161 // returned error is a wrapper error, implementations should make sure that
William Kurkianea869482019-04-09 15:16:11 -0400162 // the error implements Temporary() to have the correct retry behaviors.
Abhay Kumara61c5222025-11-10 07:32:50 +0000163 // Additionally, ClientHandshakeInfo data will be available via the context
164 // passed to this call.
165 //
166 // The second argument to this method is the `:authority` header value used
167 // while creating new streams on this connection after authentication
168 // succeeds. Implementations must use this as the server name during the
169 // authentication handshake.
William Kurkianea869482019-04-09 15:16:11 -0400170 //
171 // If the returned net.Conn is closed, it MUST close the net.Conn provided.
172 ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
173 // ServerHandshake does the authentication handshake for servers. It returns
174 // the authenticated connection and the corresponding auth information about
Abhay Kumara61c5222025-11-10 07:32:50 +0000175 // the connection. The auth information should embed CommonAuthInfo to return additional information
176 // about the credentials.
William Kurkianea869482019-04-09 15:16:11 -0400177 //
178 // If the returned net.Conn is closed, it MUST close the net.Conn provided.
179 ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
180 // Info provides the ProtocolInfo of this TransportCredentials.
181 Info() ProtocolInfo
182 // Clone makes a copy of this TransportCredentials.
183 Clone() TransportCredentials
Abhay Kumara61c5222025-11-10 07:32:50 +0000184 // OverrideServerName specifies the value used for the following:
185 //
186 // - verifying the hostname on the returned certificates
187 // - as SNI in the client's handshake to support virtual hosting
188 // - as the value for `:authority` header at stream creation time
189 //
190 // The provided string should be a valid `:authority` header according to
191 // [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2).
192 //
193 // Deprecated: this method is unused by gRPC. Users should use
194 // grpc.WithAuthority to override the authority on a channel instead of
195 // configuring the credentials.
William Kurkianea869482019-04-09 15:16:11 -0400196 OverrideServerName(string) error
197}
198
199// Bundle is a combination of TransportCredentials and PerRPCCredentials.
200//
201// It also contains a mode switching method, so it can be used as a combination
202// of different credential policies.
203//
204// Bundle cannot be used together with individual TransportCredentials.
205// PerRPCCredentials from Bundle will be appended to other PerRPCCredentials.
206//
207// This API is experimental.
208type Bundle interface {
Abhay Kumara61c5222025-11-10 07:32:50 +0000209 // TransportCredentials returns the transport credentials from the Bundle.
210 //
211 // Implementations must return non-nil transport credentials. If transport
212 // security is not needed by the Bundle, implementations may choose to
213 // return insecure.NewCredentials().
William Kurkianea869482019-04-09 15:16:11 -0400214 TransportCredentials() TransportCredentials
Abhay Kumara61c5222025-11-10 07:32:50 +0000215
216 // PerRPCCredentials returns the per-RPC credentials from the Bundle.
217 //
218 // May be nil if per-RPC credentials are not needed.
William Kurkianea869482019-04-09 15:16:11 -0400219 PerRPCCredentials() PerRPCCredentials
Abhay Kumara61c5222025-11-10 07:32:50 +0000220
William Kurkianea869482019-04-09 15:16:11 -0400221 // NewWithMode should make a copy of Bundle, and switch mode. Modifying the
222 // existing Bundle may cause races.
223 //
224 // NewWithMode returns nil if the requested mode is not supported.
225 NewWithMode(mode string) (Bundle, error)
226}
227
Devmalya Pauldd23a992019-11-14 07:06:31 +0000228// RequestInfo contains request data attached to the context passed to GetRequestMetadata calls.
229//
230// This API is experimental.
231type RequestInfo struct {
232 // The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method")
233 Method string
Abhay Kumara61c5222025-11-10 07:32:50 +0000234 // AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake)
235 AuthInfo AuthInfo
Devmalya Pauldd23a992019-11-14 07:06:31 +0000236}
237
Abhay Kumara61c5222025-11-10 07:32:50 +0000238// requestInfoKey is a struct to be used as the key to store RequestInfo in a
239// context.
Devmalya Pauldd23a992019-11-14 07:06:31 +0000240type requestInfoKey struct{}
241
242// RequestInfoFromContext extracts the RequestInfo from the context if it exists.
243//
244// This API is experimental.
245func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
246 ri, ok = ctx.Value(requestInfoKey{}).(RequestInfo)
Abhay Kumara61c5222025-11-10 07:32:50 +0000247 return ri, ok
Devmalya Pauldd23a992019-11-14 07:06:31 +0000248}
249
Abhay Kumara61c5222025-11-10 07:32:50 +0000250// NewContextWithRequestInfo creates a new context from ctx and attaches ri to it.
251//
252// This RequestInfo will be accessible via RequestInfoFromContext.
253//
254// Intended to be used from tests for PerRPCCredentials implementations (that
255// often need to check connection's SecurityLevel). Should not be used from
256// non-test code: the gRPC client already prepares a context with the correct
257// RequestInfo attached when calling PerRPCCredentials.GetRequestMetadata.
258//
259// This API is experimental.
260func NewContextWithRequestInfo(ctx context.Context, ri RequestInfo) context.Context {
261 return context.WithValue(ctx, requestInfoKey{}, ri)
262}
263
264// ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes
265// it possible to pass arbitrary data to the handshaker from gRPC, resolver,
266// balancer etc. Individual credential implementations control the actual
267// format of the data that they are willing to receive.
268//
269// This API is experimental.
270type ClientHandshakeInfo struct {
271 // Attributes contains the attributes for the address. It could be provided
272 // by the gRPC, resolver, balancer etc.
273 Attributes *attributes.Attributes
274}
275
276// ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored
277// in ctx.
278//
279// This API is experimental.
280func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {
281 chi, _ := icredentials.ClientHandshakeInfoFromContext(ctx).(ClientHandshakeInfo)
282 return chi
283}
284
285// CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
286// It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
287// or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
288//
289// This API is experimental.
290func CheckSecurityLevel(ai AuthInfo, level SecurityLevel) error {
291 type internalInfo interface {
292 GetCommonAuthInfo() CommonAuthInfo
Devmalya Pauldd23a992019-11-14 07:06:31 +0000293 }
Abhay Kumara61c5222025-11-10 07:32:50 +0000294 if ai == nil {
295 return errors.New("AuthInfo is nil")
296 }
297 if ci, ok := ai.(internalInfo); ok {
298 // CommonAuthInfo.SecurityLevel has an invalid value.
299 if ci.GetCommonAuthInfo().SecurityLevel == InvalidSecurityLevel {
300 return nil
301 }
302 if ci.GetCommonAuthInfo().SecurityLevel < level {
303 return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
304 }
305 }
306 // The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
307 return nil
308}
309
310// ChannelzSecurityInfo defines the interface that security protocols should implement
311// in order to provide security info to channelz.
312//
313// This API is experimental.
314type ChannelzSecurityInfo interface {
315 GetSecurityValue() ChannelzSecurityValue
316}
317
318// ChannelzSecurityValue defines the interface that GetSecurityValue() return value
319// should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
320// and *OtherChannelzSecurityValue.
321//
322// This API is experimental.
323type ChannelzSecurityValue interface {
324 isChannelzSecurityValue()
325}
326
327// OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
328// from GetSecurityValue(), which contains protocol specific security info. Note
329// the Value field will be sent to users of channelz requesting channel info, and
330// thus sensitive info should better be avoided.
331//
332// This API is experimental.
333type OtherChannelzSecurityValue struct {
334 ChannelzSecurityValue
335 Name string
336 Value proto.Message
Devmalya Pauldd23a992019-11-14 07:06:31 +0000337}