Skip to content

Commit e823a30

Browse files
authored
Expose configuration to set maximum number of PKCS#11 sessions (#52870)
The PKCS#11 that we use defaults to allowing 1024 concurrent sessions. If an HSM is configured with a lower limit it results in broken UX since the PKCS#11 library does not reuse open and available sessions until it has opened the maximum number of sessions that it can. While the library behavior is out of our control, we now allow users the ability to specify what their desired max and propagate it on to the PKCS#11 library so that it will not open more sessions than the HSM will allow. The auth config reference was updated to include `ca_key_params`. While these config options were somewhat discoverable via individual HSM guides, they were not mentioned in the auth reference.
1 parent 1ea6fc2 commit e823a30

File tree

7 files changed

+82
-4
lines changed

7 files changed

+82
-4
lines changed

docs/pages/admin-guides/deploy-a-cluster/hsm.mdx

+9
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ auth_service:
285285
pin: "<CU_username>:<CU_password>"
286286
# pin_path can optionally be used to read the pin from a file
287287
# pin_path: /path/to/pin_file
288+
289+
# max_sessions configures the maximum number of open sessions for the HSM.
290+
# If not set, it will default to the minimum of 1024 or the MaxRWSessionCount
291+
# reported by the PKCS#11 module for the token. If set, must be greater than 1.
292+
max_sessions: 10
288293
```
289294
</TabItem>
290295
@@ -309,6 +314,10 @@ auth_service:
309314
pin: "85cfpassword"
310315
# pin_path can optionally be used to read the pin from a file
311316
# pin_path: /path/to/pin_file
317+
318+
# Optionally specify the maximum number of open sessions for the HSM.
319+
# If not set, it will default to 1024. If set, must be greater than 1.
320+
max_sessions: 10
312321
```
313322
</TabItem>
314323
</Tabs>

docs/pages/includes/config-reference/auth-service.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,34 @@ auth_service:
432432
report_results: s3://audit-long-term/report_results
433433
# (Optional) Athena workgroup used by access monitoring queries (if not set, the default primary workgroup will be used).
434434
workgroup: access_monitoring_workgroup
435+
# Enables storing CAs in an external Hardware Security Module(HSM) or Key Management Service(KMS)
436+
# Only one of the options can be enbabled at a given time.
437+
ca_key_params:
438+
# Persist CAs to Google Cloud KMS.
439+
gcp_kms:
440+
# The fully qualified path to the GCP key ring where CAs are to be stored.
441+
keyring: 'projects/<your-gcp-project>/locations/<location>/keyRings/<your-teleport-keyring>'
442+
# The protection level of the keys. Must be either SOFTWARE or HSM.
443+
protection_level: 'SOFTWARE'
444+
# Persist CAs to AWS KMS.
445+
aws_kms:
446+
# The AWS account where keys should be stored.
447+
account: '123456789012'
448+
# The AWS region where keys will be stored.
449+
region: 'us-west-2'
450+
# Persist CAs to a PKCS#11 compliant HSM.
451+
pkcs11:
452+
# this is the default install location of the PKCS#11 module for the HSM.
453+
module_path: /opt/cloudhsm/lib/libcloudhsm_pkcs11.so
454+
# slot_number is the PKCS#11 slot number to use for HSM connections.
455+
slot_number: 0
456+
# token_label is the label of the PKCS#11 token to use for HSM connections.
457+
token_label: 'hsm1'
458+
# max_sessions configures the maximum number of open sessions for the HSM.
459+
# If not set, it will default to the minimum of 1024 or the MaxRWSessionCount
460+
# reported by the PKCS#11 module for the token. If set, must be greater than 1.
461+
max_sessions: 10
462+
# pin is the PKCS#11 pin to use for HSM connections.
463+
pin: '0001password'
464+
# pin_path can optionally be used to read the pin from a file
465+
# pin_path: /path/to/pin_file

lib/auth/keystore/pkcs11.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ type pkcs11KeyStore struct {
5151

5252
func newPKCS11KeyStore(config *servicecfg.PKCS11Config, opts *Options) (*pkcs11KeyStore, error) {
5353
cryptoConfig := &crypto11.Config{
54-
Path: config.Path,
55-
TokenLabel: config.TokenLabel,
56-
SlotNumber: config.SlotNumber,
57-
Pin: config.PIN,
54+
Path: config.Path,
55+
TokenLabel: config.TokenLabel,
56+
SlotNumber: config.SlotNumber,
57+
Pin: config.PIN,
58+
MaxSessions: config.MaxSessions,
5859
}
5960

6061
ctx, err := crypto11.Configure(cryptoConfig)

lib/config/configuration.go

+1
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,7 @@ func applyPKCS11Config(pkcs11Config *PKCS11, cfg *servicecfg.Config) error {
11381138

11391139
cfg.Auth.KeyStore.PKCS11.TokenLabel = pkcs11Config.TokenLabel
11401140
cfg.Auth.KeyStore.PKCS11.SlotNumber = pkcs11Config.SlotNumber
1141+
cfg.Auth.KeyStore.PKCS11.MaxSessions = pkcs11Config.MaxSessions
11411142

11421143
cfg.Auth.KeyStore.PKCS11.PIN = pkcs11Config.PIN
11431144
if pkcs11Config.PINPath != "" {

lib/config/configuration_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -3217,6 +3217,27 @@ func TestApplyKeyStoreConfig(t *testing.T) {
32173217
worldReadablePinFilePath,
32183218
),
32193219
},
3220+
{
3221+
name: "correct config with max sessions",
3222+
auth: Auth{
3223+
CAKeyParams: &CAKeyParams{
3224+
PKCS11: &PKCS11{
3225+
ModulePath: securePKCS11LibPath,
3226+
TokenLabel: "foo",
3227+
SlotNumber: &slotNumber,
3228+
MaxSessions: 100,
3229+
},
3230+
},
3231+
},
3232+
want: servicecfg.KeystoreConfig{
3233+
PKCS11: servicecfg.PKCS11Config{
3234+
TokenLabel: "foo",
3235+
SlotNumber: &slotNumber,
3236+
MaxSessions: 100,
3237+
Path: securePKCS11LibPath,
3238+
},
3239+
},
3240+
},
32203241
{
32213242
name: "correct gcp config",
32223243
auth: Auth{

lib/config/fileconf.go

+2
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,8 @@ type PKCS11 struct {
895895
// Trailing newlines will be removed, other whitespace will be left. Set
896896
// this or Pin to set the pin.
897897
PINPath string `yaml:"pin_path,omitempty"`
898+
// MaxSessions is the upper limit of sessions allowed by the HSM.
899+
MaxSessions int `yaml:"max_sessions"`
898900
}
899901

900902
// GoogleCloudKMS configures Google Cloud Key Management Service to to be used for

lib/service/servicecfg/auth.go

+13
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ type PKCS11Config struct {
242242
TokenLabel string
243243
// PIN is the PKCS11 PIN for the given token.
244244
PIN string
245+
// MaxSessions is the upper limit of sessions allowed by the HSM.
246+
MaxSessions int
245247
}
246248

247249
// CheckAndSetDefaults checks that required parameters of the config are
@@ -253,6 +255,17 @@ func (cfg *PKCS11Config) CheckAndSetDefaults() error {
253255
if cfg.SlotNumber == nil && cfg.TokenLabel == "" {
254256
return trace.BadParameter("must provide one of SlotNumber or TokenLabel")
255257
}
258+
259+
switch {
260+
case cfg.MaxSessions < 0:
261+
return trace.BadParameter("the value of PKCS11 MaxSessions must not be negative")
262+
case cfg.MaxSessions == 1:
263+
return trace.BadParameter("the minimum value for PKCS11 MaxSessions is 2")
264+
case cfg.MaxSessions == 0:
265+
// A value of zero is acceptable and indicates to the pkcs11 library to use the default value.
266+
default:
267+
}
268+
256269
return nil
257270
}
258271

0 commit comments

Comments
 (0)