12 "github.com/aws/aws-sdk-go/aws"
13 "github.com/aws/aws-sdk-go/aws/awserr"
14 "github.com/aws/aws-sdk-go/aws/client"
15 "github.com/aws/aws-sdk-go/aws/corehandlers"
16 "github.com/aws/aws-sdk-go/aws/credentials"
17 "github.com/aws/aws-sdk-go/aws/credentials/processcreds"
18 "github.com/aws/aws-sdk-go/aws/credentials/stscreds"
19 "github.com/aws/aws-sdk-go/aws/csm"
20 "github.com/aws/aws-sdk-go/aws/defaults"
21 "github.com/aws/aws-sdk-go/aws/endpoints"
22 "github.com/aws/aws-sdk-go/aws/request"
23 "github.com/aws/aws-sdk-go/internal/shareddefaults"
27 // ErrCodeSharedConfig represents an error that occurs in the shared
28 // configuration logic
29 ErrCodeSharedConfig = "SharedConfigErr"
32 // ErrSharedConfigSourceCollision will be returned if a section contains both
33 // source_profile and credential_source
34 var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil)
36 // ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
37 // variables are empty and Environment was set as the credential source
38 var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil)
40 // ErrSharedConfigInvalidCredSource will be returned if an invalid credential source was provided
41 var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil)
43 // A Session provides a central location to create service clients from and
44 // store configurations and request handlers for those services.
46 // Sessions are safe to create service clients concurrently, but it is not safe
47 // to mutate the Session concurrently.
49 // The Session satisfies the service client's client.ConfigProvider.
52 Handlers request.Handlers
55 // New creates a new instance of the handlers merging in the provided configs
56 // on top of the SDK's default configurations. Once the Session is created it
57 // can be mutated to modify the Config or Handlers. The Session is safe to be
58 // read concurrently, but it should not be written to concurrently.
60 // If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New
61 // method could now encounter an error when loading the configuration. When
62 // The environment variable is set, and an error occurs, New will return a
63 // session that will fail all requests reporting the error that occurred while
64 // loading the session. Use NewSession to get the error when creating the
67 // If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
68 // the shared config file (~/.aws/config) will also be loaded, in addition to
69 // the shared credentials file (~/.aws/credentials). Values set in both the
70 // shared config, and shared credentials will be taken from the shared
73 // Deprecated: Use NewSession functions to create sessions instead. NewSession
74 // has the same functionality as New except an error can be returned when the
75 // func is called instead of waiting to receive an error until a request is made.
76 func New(cfgs ...*aws.Config) *Session {
77 // load initial config from environment
78 envCfg := loadEnvConfig()
80 if envCfg.EnableSharedConfig {
83 s, err := NewSessionWithOptions(Options{
85 SharedConfigState: SharedConfigEnable,
88 // Old session.New expected all errors to be discovered when
89 // a request is made, and would report the errors then. This
90 // needs to be replicated if an error occurs while creating
92 msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " +
93 "Use session.NewSession to handle errors occurring during session creation."
95 // Session creation failed, need to report the error and prevent
96 // any requests from succeeding.
97 s = &Session{Config: defaults.Config()}
98 s.Config.MergeIn(cfgs...)
99 s.Config.Logger.Log("ERROR:", msg, "Error:", err)
100 s.Handlers.Validate.PushBack(func(r *request.Request) {
108 s := deprecatedNewSession(cfgs...)
109 if envCfg.CSMEnabled {
110 enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
116 // NewSession returns a new Session created from SDK defaults, config files,
117 // environment, and user provided config files. Once the Session is created
118 // it can be mutated to modify the Config or Handlers. The Session is safe to
119 // be read concurrently, but it should not be written to concurrently.
121 // If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
122 // the shared config file (~/.aws/config) will also be loaded in addition to
123 // the shared credentials file (~/.aws/credentials). Values set in both the
124 // shared config, and shared credentials will be taken from the shared
125 // credentials file. Enabling the Shared Config will also allow the Session
126 // to be built with retrieving credentials with AssumeRole set in the config.
128 // See the NewSessionWithOptions func for information on how to override or
129 // control through code how the Session will be created. Such as specifying the
130 // config profile, and controlling if shared config is enabled or not.
131 func NewSession(cfgs ...*aws.Config) (*Session, error) {
133 opts.Config.MergeIn(cfgs...)
135 return NewSessionWithOptions(opts)
138 // SharedConfigState provides the ability to optionally override the state
139 // of the session's creation based on the shared config being enabled or
141 type SharedConfigState int
144 // SharedConfigStateFromEnv does not override any state of the
145 // AWS_SDK_LOAD_CONFIG env var. It is the default value of the
146 // SharedConfigState type.
147 SharedConfigStateFromEnv SharedConfigState = iota
149 // SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value
150 // and disables the shared config functionality.
153 // SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value
154 // and enables the shared config functionality.
158 // Options provides the means to control how a Session is created and what
159 // configuration values will be loaded.
161 type Options struct {
162 // Provides config values for the SDK to use when creating service clients
163 // and making API requests to services. Any value set in with this field
164 // will override the associated value provided by the SDK defaults,
165 // environment or config files where relevant.
167 // If not set, configuration values from from SDK defaults, environment,
168 // config will be used.
171 // Overrides the config profile the Session should be created from. If not
172 // set the value of the environment variable will be loaded (AWS_PROFILE,
173 // or AWS_DEFAULT_PROFILE if the Shared Config is enabled).
175 // If not set and environment variables are not set the "default"
176 // (DefaultSharedConfigProfile) will be used as the profile to load the
177 // session config from.
180 // Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG
181 // environment variable. By default a Session will be created using the
182 // value provided by the AWS_SDK_LOAD_CONFIG environment variable.
184 // Setting this value to SharedConfigEnable or SharedConfigDisable
185 // will allow you to override the AWS_SDK_LOAD_CONFIG environment variable
186 // and enable or disable the shared config functionality.
187 SharedConfigState SharedConfigState
189 // Ordered list of files the session will load configuration from.
190 // It will override environment variable AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE.
191 SharedConfigFiles []string
193 // When the SDK's shared config is configured to assume a role with MFA
194 // this option is required in order to provide the mechanism that will
195 // retrieve the MFA token. There is no default value for this field. If
196 // it is not set an error will be returned when creating the session.
198 // This token provider will be called when ever the assumed role's
199 // credentials need to be refreshed. Within the context of service clients
200 // all sharing the same session the SDK will ensure calls to the token
201 // provider are atomic. When sharing a token provider across multiple
202 // sessions additional synchronization logic is needed to ensure the
203 // token providers do not introduce race conditions. It is recommend to
204 // share the session where possible.
206 // stscreds.StdinTokenProvider is a basic implementation that will prompt
207 // from stdin for the MFA token code.
209 // This field is only used if the shared configuration is enabled, and
210 // the config enables assume role wit MFA via the mfa_serial field.
211 AssumeRoleTokenProvider func() (string, error)
213 // Reader for a custom Credentials Authority (CA) bundle in PEM format that
214 // the SDK will use instead of the default system's root CA bundle. Use this
215 // only if you want to replace the CA bundle the SDK uses for TLS requests.
217 // Enabling this option will attempt to merge the Transport into the SDK's HTTP
218 // client. If the client's Transport is not a http.Transport an error will be
219 // returned. If the Transport's TLS config is set this option will cause the SDK
220 // to overwrite the Transport's TLS config's RootCAs value. If the CA
221 // bundle reader contains multiple certificates all of them will be loaded.
223 // The Session option CustomCABundle is also available when creating sessions
224 // to also enable this feature. CustomCABundle session option field has priority
225 // over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
226 CustomCABundle io.Reader
229 // NewSessionWithOptions returns a new Session created from SDK defaults, config files,
230 // environment, and user provided config files. This func uses the Options
231 // values to configure how the Session is created.
233 // If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
234 // the shared config file (~/.aws/config) will also be loaded in addition to
235 // the shared credentials file (~/.aws/credentials). Values set in both the
236 // shared config, and shared credentials will be taken from the shared
237 // credentials file. Enabling the Shared Config will also allow the Session
238 // to be built with retrieving credentials with AssumeRole set in the config.
240 // // Equivalent to session.New
241 // sess := session.Must(session.NewSessionWithOptions(session.Options{}))
243 // // Specify profile to load for the session's config
244 // sess := session.Must(session.NewSessionWithOptions(session.Options{
245 // Profile: "profile_name",
248 // // Specify profile for config and region for requests
249 // sess := session.Must(session.NewSessionWithOptions(session.Options{
250 // Config: aws.Config{Region: aws.String("us-east-1")},
251 // Profile: "profile_name",
254 // // Force enable Shared Config support
255 // sess := session.Must(session.NewSessionWithOptions(session.Options{
256 // SharedConfigState: session.SharedConfigEnable,
258 func NewSessionWithOptions(opts Options) (*Session, error) {
260 if opts.SharedConfigState == SharedConfigEnable {
261 envCfg = loadSharedEnvConfig()
263 envCfg = loadEnvConfig()
266 if len(opts.Profile) > 0 {
267 envCfg.Profile = opts.Profile
270 switch opts.SharedConfigState {
271 case SharedConfigDisable:
272 envCfg.EnableSharedConfig = false
273 case SharedConfigEnable:
274 envCfg.EnableSharedConfig = true
277 // Only use AWS_CA_BUNDLE if session option is not provided.
278 if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
279 f, err := os.Open(envCfg.CustomCABundle)
281 return nil, awserr.New("LoadCustomCABundleError",
282 "failed to open custom CA bundle PEM file", err)
285 opts.CustomCABundle = f
288 return newSession(opts, envCfg, &opts.Config)
291 // Must is a helper function to ensure the Session is valid and there was no
292 // error when calling a NewSession function.
294 // This helper is intended to be used in variable initialization to load the
295 // Session and configuration at startup. Such as:
297 // var sess = session.Must(session.NewSession())
298 func Must(sess *Session, err error) *Session {
306 func deprecatedNewSession(cfgs ...*aws.Config) *Session {
307 cfg := defaults.Config()
308 handlers := defaults.Handlers()
310 // Apply the passed in configs so the configuration can be applied to the
311 // default credential chain
313 if cfg.EndpointResolver == nil {
314 // An endpoint resolver is required for a session to be able to provide
315 // endpoints for service client configurations.
316 cfg.EndpointResolver = endpoints.DefaultResolver()
318 cfg.Credentials = defaults.CredChain(cfg, handlers)
320 // Reapply any passed in configs to override credentials if set
332 func enableCSM(handlers *request.Handlers, clientID string, port string, logger aws.Logger) {
333 logger.Log("Enabling CSM")
335 port = csm.DefaultPort
338 r, err := csm.Start(clientID, "127.0.0.1:"+port)
342 r.InjectHandlers(handlers)
345 func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
346 cfg := defaults.Config()
347 handlers := defaults.Handlers()
349 // Get a merged version of the user provided config to determine if
351 userCfg := &aws.Config{}
352 userCfg.MergeIn(cfgs...)
354 // Ordered config files will be loaded in with later files overwriting
355 // previous config file values.
356 var cfgFiles []string
357 if opts.SharedConfigFiles != nil {
358 cfgFiles = opts.SharedConfigFiles
360 cfgFiles = []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile}
361 if !envCfg.EnableSharedConfig {
362 // The shared config file (~/.aws/config) is only loaded if instructed
363 // to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG).
364 cfgFiles = cfgFiles[1:]
368 // Load additional config from file(s)
369 sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles)
374 if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
384 if envCfg.CSMEnabled {
385 enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
388 // Setup HTTP client with custom cert bundle if enabled
389 if opts.CustomCABundle != nil {
390 if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil {
398 func loadCustomCABundle(s *Session, bundle io.Reader) error {
399 var t *http.Transport
400 switch v := s.Config.HTTPClient.Transport.(type) {
401 case *http.Transport:
404 if s.Config.HTTPClient.Transport != nil {
405 return awserr.New("LoadCustomCABundleError",
406 "unable to load custom CA bundle, HTTPClient's transport unsupported type", nil)
410 // Nil transport implies `http.DefaultTransport` should be used. Since
411 // the SDK cannot modify, nor copy the `DefaultTransport` specifying
412 // the values the next closest behavior.
413 t = getCABundleTransport()
416 p, err := loadCertPool(bundle)
420 if t.TLSClientConfig == nil {
421 t.TLSClientConfig = &tls.Config{}
423 t.TLSClientConfig.RootCAs = p
425 s.Config.HTTPClient.Transport = t
430 func loadCertPool(r io.Reader) (*x509.CertPool, error) {
431 b, err := ioutil.ReadAll(r)
433 return nil, awserr.New("LoadCustomCABundleError",
434 "failed to read custom CA bundle PEM file", err)
437 p := x509.NewCertPool()
438 if !p.AppendCertsFromPEM(b) {
439 return nil, awserr.New("LoadCustomCABundleError",
440 "failed to load custom CA bundle PEM file", err)
446 func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error {
447 // Merge in user provided configuration
450 // Region if not already set by user
451 if len(aws.StringValue(cfg.Region)) == 0 {
452 if len(envCfg.Region) > 0 {
453 cfg.WithRegion(envCfg.Region)
454 } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 {
455 cfg.WithRegion(sharedCfg.Region)
459 if cfg.EnableEndpointDiscovery == nil {
460 if envCfg.EnableEndpointDiscovery != nil {
461 cfg.WithEndpointDiscovery(*envCfg.EnableEndpointDiscovery)
462 } else if envCfg.EnableSharedConfig && sharedCfg.EnableEndpointDiscovery != nil {
463 cfg.WithEndpointDiscovery(*sharedCfg.EnableEndpointDiscovery)
467 // Configure credentials if not already set
468 if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
470 // inspect the profile to see if a credential source has been specified.
471 if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.CredentialSource) > 0 {
473 // if both credential_source and source_profile have been set, return an error
474 // as this is undefined behavior.
475 if len(sharedCfg.AssumeRole.SourceProfile) > 0 {
476 return ErrSharedConfigSourceCollision
479 // valid credential source values
481 credSourceEc2Metadata = "Ec2InstanceMetadata"
482 credSourceEnvironment = "Environment"
483 credSourceECSContainer = "EcsContainer"
486 switch sharedCfg.AssumeRole.CredentialSource {
487 case credSourceEc2Metadata:
489 p := defaults.RemoteCredProvider(cfgCp, handlers)
490 cfgCp.Credentials = credentials.NewCredentials(p)
492 if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
493 // AssumeRole Token provider is required if doing Assume Role
495 return AssumeRoleTokenProviderNotSetError{}
498 cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
499 case credSourceEnvironment:
500 cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
503 case credSourceECSContainer:
504 if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
505 return ErrSharedConfigECSContainerEnvVarEmpty
509 p := defaults.RemoteCredProvider(cfgCp, handlers)
510 creds := credentials.NewCredentials(p)
512 cfg.Credentials = creds
514 return ErrSharedConfigInvalidCredSource
520 if len(envCfg.Creds.AccessKeyID) > 0 {
521 cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
524 } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
526 cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(
527 sharedCfg.AssumeRoleSource.Creds,
530 if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
531 // AssumeRole Token provider is required if doing Assume Role
533 return AssumeRoleTokenProviderNotSetError{}
536 cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
537 } else if len(sharedCfg.Creds.AccessKeyID) > 0 {
538 cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
541 } else if len(sharedCfg.CredentialProcess) > 0 {
542 cfg.Credentials = processcreds.NewCredentials(
543 sharedCfg.CredentialProcess,
546 // Fallback to default credentials provider, include mock errors
547 // for the credential chain so user can identify why credentials
548 // failed to be retrieved.
549 cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{
550 VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
551 Providers: []credentials.Provider{
552 &credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)},
553 &credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)},
554 defaults.RemoteCredProvider(*cfg, handlers),
563 func assumeRoleCredentials(cfg aws.Config, handlers request.Handlers, sharedCfg sharedConfig, sessOpts Options) *credentials.Credentials {
564 return stscreds.NewCredentials(
567 Handlers: handlers.Copy(),
569 sharedCfg.AssumeRole.RoleARN,
570 func(opt *stscreds.AssumeRoleProvider) {
571 opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
573 // Assume role with external ID
574 if len(sharedCfg.AssumeRole.ExternalID) > 0 {
575 opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
578 // Assume role with MFA
579 if len(sharedCfg.AssumeRole.MFASerial) > 0 {
580 opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
581 opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
587 // AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
588 // MFAToken option is not set when shared config is configured load assume a
589 // role with an MFA token.
590 type AssumeRoleTokenProviderNotSetError struct{}
592 // Code is the short id of the error.
593 func (e AssumeRoleTokenProviderNotSetError) Code() string {
594 return "AssumeRoleTokenProviderNotSetError"
597 // Message is the description of the error
598 func (e AssumeRoleTokenProviderNotSetError) Message() string {
599 return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
602 // OrigErr is the underlying error that caused the failure.
603 func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
607 // Error satisfies the error interface.
608 func (e AssumeRoleTokenProviderNotSetError) Error() string {
609 return awserr.SprintError(e.Code(), e.Message(), "", nil)
612 type credProviderError struct {
616 var emptyCreds = credentials.Value{}
618 func (c credProviderError) Retrieve() (credentials.Value, error) {
619 return credentials.Value{}, c.Err
621 func (c credProviderError) IsExpired() bool {
625 func initHandlers(s *Session) {
626 // Add the Validate parameter handler if it is not disabled.
627 s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
628 if !aws.BoolValue(s.Config.DisableParamValidation) {
629 s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
633 // Copy creates and returns a copy of the current Session, coping the config
634 // and handlers. If any additional configs are provided they will be merged
635 // on top of the Session's copied config.
637 // // Create a copy of the current Session, configured for the us-west-2 region.
638 // sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
639 func (s *Session) Copy(cfgs ...*aws.Config) *Session {
640 newSession := &Session{
641 Config: s.Config.Copy(cfgs...),
642 Handlers: s.Handlers.Copy(),
645 initHandlers(newSession)
650 // ClientConfig satisfies the client.ConfigProvider interface and is used to
651 // configure the service client instances. Passing the Session to the service
652 // client's constructor (New) will use this method to configure the client.
653 func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
654 // Backwards compatibility, the error will be eaten if user calls ClientConfig
655 // directly. All SDK services will use ClientconfigWithError.
656 cfg, _ := s.clientConfigWithErr(serviceName, cfgs...)
661 func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) {
664 var resolved endpoints.ResolvedEndpoint
667 region := aws.StringValue(s.Config.Region)
669 if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 {
670 resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL))
671 resolved.SigningRegion = region
673 resolved, err = s.Config.EndpointResolver.EndpointFor(
675 func(opt *endpoints.Options) {
676 opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL)
677 opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack)
679 // Support the condition where the service is modeled but its
680 // endpoint metadata is not available.
681 opt.ResolveUnknownService = true
686 return client.Config{
688 Handlers: s.Handlers,
689 Endpoint: resolved.URL,
690 SigningRegion: resolved.SigningRegion,
691 SigningNameDerived: resolved.SigningNameDerived,
692 SigningName: resolved.SigningName,
696 // ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception
697 // that the EndpointResolver will not be used to resolve the endpoint. The only
698 // endpoint set must come from the aws.Config.Endpoint field.
699 func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Config {
702 var resolved endpoints.ResolvedEndpoint
704 region := aws.StringValue(s.Config.Region)
706 if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 {
707 resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL))
708 resolved.SigningRegion = region
711 return client.Config{
713 Handlers: s.Handlers,
714 Endpoint: resolved.URL,
715 SigningRegion: resolved.SigningRegion,
716 SigningNameDerived: resolved.SigningNameDerived,
717 SigningName: resolved.SigningName,