diff --git a/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx b/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx index 528d3ed9213c2..bb42e9fa35ebd 100644 --- a/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx +++ b/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx @@ -285,6 +285,11 @@ auth_service: pin: ":" # pin_path can optionally be used to read the pin from a file # pin_path: /path/to/pin_file + + # max_sessions configures the maximum number of open sessions for the HSM. + # If not set, it will default to the minimum of 1024 or the MaxRWSessionCount + # reported by the PKCS#11 module for the token. If set, must be greater than 1. + max_sessions: 10 ``` @@ -309,6 +314,10 @@ auth_service: pin: "85cfpassword" # pin_path can optionally be used to read the pin from a file # pin_path: /path/to/pin_file + + # Optionally specify the maximum number of open sessions for the HSM. + # If not set, it will default to 1024. If set, must be greater than 1. + max_sessions: 10 ``` diff --git a/docs/pages/includes/config-reference/auth-service.yaml b/docs/pages/includes/config-reference/auth-service.yaml index 483bbf711c342..2d8c04fb10ee1 100644 --- a/docs/pages/includes/config-reference/auth-service.yaml +++ b/docs/pages/includes/config-reference/auth-service.yaml @@ -432,3 +432,34 @@ auth_service: report_results: s3://audit-long-term/report_results # (Optional) Athena workgroup used by access monitoring queries (if not set, the default primary workgroup will be used). workgroup: access_monitoring_workgroup + # Enables storing CAs in an external Hardware Security Module(HSM) or Key Management Service(KMS) + # Only one of the options can be enbabled at a given time. + ca_key_params: + # Persist CAs to Google Cloud KMS. + gcp_kms: + # The fully qualified path to the GCP key ring where CAs are to be stored. + keyring: 'projects//locations//keyRings/' + # The protection level of the keys. Must be either SOFTWARE or HSM. + protection_level: 'SOFTWARE' + # Persist CAs to AWS KMS. + aws_kms: + # The AWS account where keys should be stored. + account: '123456789012' + # The AWS region where keys will be stored. + region: 'us-west-2' + # Persist CAs to a PKCS#11 compliant HSM. + pkcs11: + # this is the default install location of the PKCS#11 module for the HSM. + module_path: /opt/cloudhsm/lib/libcloudhsm_pkcs11.so + # slot_number is the PKCS#11 slot number to use for HSM connections. + slot_number: 0 + # token_label is the label of the PKCS#11 token to use for HSM connections. + token_label: 'hsm1' + # max_sessions configures the maximum number of open sessions for the HSM. + # If not set, it will default to the minimum of 1024 or the MaxRWSessionCount + # reported by the PKCS#11 module for the token. If set, must be greater than 1. + max_sessions: 10 + # pin is the PKCS#11 pin to use for HSM connections. + pin: '0001password' + # pin_path can optionally be used to read the pin from a file + # pin_path: /path/to/pin_file diff --git a/lib/auth/keystore/pkcs11.go b/lib/auth/keystore/pkcs11.go index 73c224148f707..2184e4afce7a2 100644 --- a/lib/auth/keystore/pkcs11.go +++ b/lib/auth/keystore/pkcs11.go @@ -51,10 +51,11 @@ type pkcs11KeyStore struct { func newPKCS11KeyStore(config *servicecfg.PKCS11Config, opts *Options) (*pkcs11KeyStore, error) { cryptoConfig := &crypto11.Config{ - Path: config.Path, - TokenLabel: config.TokenLabel, - SlotNumber: config.SlotNumber, - Pin: config.PIN, + Path: config.Path, + TokenLabel: config.TokenLabel, + SlotNumber: config.SlotNumber, + Pin: config.PIN, + MaxSessions: config.MaxSessions, } ctx, err := crypto11.Configure(cryptoConfig) diff --git a/lib/config/configuration.go b/lib/config/configuration.go index 38a2b76262d13..77a82ea2d5b8f 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -994,6 +994,7 @@ func applyPKCS11Config(pkcs11Config *PKCS11, cfg *servicecfg.Config) error { cfg.Auth.KeyStore.PKCS11.TokenLabel = pkcs11Config.TokenLabel cfg.Auth.KeyStore.PKCS11.SlotNumber = pkcs11Config.SlotNumber + cfg.Auth.KeyStore.PKCS11.MaxSessions = pkcs11Config.MaxSessions cfg.Auth.KeyStore.PKCS11.PIN = pkcs11Config.PIN if pkcs11Config.PINPath != "" { diff --git a/lib/config/configuration_test.go b/lib/config/configuration_test.go index f8fb66305d968..ec8161ac7c6eb 100644 --- a/lib/config/configuration_test.go +++ b/lib/config/configuration_test.go @@ -3217,6 +3217,27 @@ func TestApplyKeyStoreConfig(t *testing.T) { worldReadablePinFilePath, ), }, + { + name: "correct config with max sessions", + auth: Auth{ + CAKeyParams: &CAKeyParams{ + PKCS11: &PKCS11{ + ModulePath: securePKCS11LibPath, + TokenLabel: "foo", + SlotNumber: &slotNumber, + MaxSessions: 100, + }, + }, + }, + want: servicecfg.KeystoreConfig{ + PKCS11: servicecfg.PKCS11Config{ + TokenLabel: "foo", + SlotNumber: &slotNumber, + MaxSessions: 100, + Path: securePKCS11LibPath, + }, + }, + }, { name: "correct gcp config", auth: Auth{ diff --git a/lib/config/fileconf.go b/lib/config/fileconf.go index 781841a6f85c6..daa70d9f545c0 100644 --- a/lib/config/fileconf.go +++ b/lib/config/fileconf.go @@ -896,6 +896,8 @@ type PKCS11 struct { // Trailing newlines will be removed, other whitespace will be left. Set // this or Pin to set the pin. PINPath string `yaml:"pin_path,omitempty"` + // MaxSessions is the upper limit of sessions allowed by the HSM. + MaxSessions int `yaml:"max_sessions"` } // GoogleCloudKMS configures Google Cloud Key Management Service to to be used for diff --git a/lib/service/servicecfg/auth.go b/lib/service/servicecfg/auth.go index a8fcfcd57b8f2..b3719d684f015 100644 --- a/lib/service/servicecfg/auth.go +++ b/lib/service/servicecfg/auth.go @@ -242,6 +242,8 @@ type PKCS11Config struct { TokenLabel string // PIN is the PKCS11 PIN for the given token. PIN string + // MaxSessions is the upper limit of sessions allowed by the HSM. + MaxSessions int } // CheckAndSetDefaults checks that required parameters of the config are @@ -253,6 +255,17 @@ func (cfg *PKCS11Config) CheckAndSetDefaults() error { if cfg.SlotNumber == nil && cfg.TokenLabel == "" { return trace.BadParameter("must provide one of SlotNumber or TokenLabel") } + + switch { + case cfg.MaxSessions < 0: + return trace.BadParameter("the value of PKCS11 MaxSessions must not be negative") + case cfg.MaxSessions == 1: + return trace.BadParameter("the minimum value for PKCS11 MaxSessions is 2") + case cfg.MaxSessions == 0: + // A value of zero is acceptable and indicates to the pkcs11 library to use the default value. + default: + } + return nil }