diff --git a/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx b/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx index 688d02f7eae53..b08146ca06738 100644 --- a/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx +++ b/docs/pages/admin-guides/deploy-a-cluster/hsm.mdx @@ -284,6 +284,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 ``` @@ -308,6 +313,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 6967c5f814c02..e2cdc903fe838 100644 --- a/docs/pages/includes/config-reference/auth-service.yaml +++ b/docs/pages/includes/config-reference/auth-service.yaml @@ -415,3 +415,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 ed48e8e789a8d..8e4630732a053 100644 --- a/lib/auth/keystore/pkcs11.go +++ b/lib/auth/keystore/pkcs11.go @@ -50,10 +50,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 326f276989fa8..5dfcfd2058e2f 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -1119,6 +1119,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 1a5b7b3a58852..836c64a8af983 100644 --- a/lib/config/configuration_test.go +++ b/lib/config/configuration_test.go @@ -3180,6 +3180,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 44e72850c65ae..baf6ac16c0d3c 100644 --- a/lib/config/fileconf.go +++ b/lib/config/fileconf.go @@ -893,6 +893,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 1b09042215aed..5f8bb96a9c316 100644 --- a/lib/service/servicecfg/auth.go +++ b/lib/service/servicecfg/auth.go @@ -235,6 +235,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 @@ -246,6 +248,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 }