diff --git a/ui/app/models/role-ssh.js b/ui/app/models/role-ssh.js
index e8f2293ad76e..f3b3c18da6a5 100644
--- a/ui/app/models/role-ssh.js
+++ b/ui/app/models/role-ssh.js
@@ -40,6 +40,7 @@ const CA_FIELDS = [
'defaultExtensions',
'allowBareDomains',
'allowSubdomains',
+ 'allowEmptyPrincipals',
'allowUserKeyIds',
'keyIdFormat',
'notBeforeDuration',
@@ -122,6 +123,10 @@ export default Model.extend({
helpText:
'Specifies if host certificates that are requested are allowed to be subdomains of those listed in Allowed Domains',
}),
+ allowEmptyPrincipals: attr('boolean', {
+ helpText:
+ 'Allow signing certificates with no valid principals (e.g. any valid principal). For backwards compatibility only. The default of false is highly recommended.',
+ }),
allowUserKeyIds: attr('boolean', {
helpText: 'Specifies if users can override the key ID for a signed certificate with the "key_id" field',
}),
diff --git a/ui/app/models/ssh-sign.js b/ui/app/models/ssh-sign.js
index 260eabf2ce39..704e8284cc57 100644
--- a/ui/app/models/ssh-sign.js
+++ b/ui/app/models/ssh-sign.js
@@ -30,7 +30,10 @@ export default Model.extend({
label: 'TTL',
editType: 'ttl',
}),
- validPrincipals: attr('string'),
+ validPrincipals: attr('string', {
+ helpText:
+ 'Specifies valid principals, either usernames or hostnames, that the certificate should be signed for. Required unless the role has specified allow_empty_principals.',
+ }),
certType: attr('string', {
defaultValue: 'user',
label: 'Certificate Type',
diff --git a/ui/app/templates/vault/cluster/secrets/backend/sign.hbs b/ui/app/templates/vault/cluster/secrets/backend/sign.hbs
index 91f19600b649..672e279f319a 100644
--- a/ui/app/templates/vault/cluster/secrets/backend/sign.hbs
+++ b/ui/app/templates/vault/cluster/secrets/backend/sign.hbs
@@ -81,48 +81,47 @@
{{#if this.model.attrs}}
- {{#each (take 1 this.model.attrs) as |attr|}}
-
- {{/each}}
+ {{#let (find-by "name" "publicKey" this.model.attrs) as |attr|}}
+
+ {{/let}}
+ {{! valid_principals is required unless allow_empty_principals is true (not recommended) }}
+ {{#let (find-by "name" "validPrincipals" this.model.attrs) as |attr|}}
+
+ {{/let}}
{{#if this.showOptions}}
- {{#each (drop 1 this.model.attrs) as |attr|}}
-
+ {{#each this.model.attrs as |attr|}}
+ {{! These attrs render above, outside of the "More options" toggle }}
+ {{#if (not (includes attr.name (array "publicKey" "validPrincipals")))}}
+
+ {{/if}}
{{/each}}
{{/if}}
{{/if}}
-
-
-
-
-
-
+
+
+
+
{{/if}}
\ No newline at end of file
diff --git a/ui/tests/acceptance/ssh-test.js b/ui/tests/acceptance/ssh-test.js
index 72e1428009a5..1758fb44b296 100644
--- a/ui/tests/acceptance/ssh-test.js
+++ b/ui/tests/acceptance/ssh-test.js
@@ -8,6 +8,7 @@ import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid';
+import { GENERAL } from 'vault/tests/helpers/general-selectors';
import authPage from 'vault/tests/pages/auth';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
import { setRunOptions } from 'ember-a11y-testing/test-support';
@@ -28,6 +29,9 @@ module('Acceptance | ssh secret backend', function (hooks) {
name: 'carole',
async fillInCreate() {
await click('[data-test-input="allowUserCertificates"]');
+ await click('[data-test-toggle-group="Options"]');
+ // it's recommended to keep allow_empty_principals false, check for testing so we don't have to input an extra field when signing a key
+ await click(GENERAL.inputByAttr('allowEmptyPrincipals'));
},
async fillInGenerate() {
await fillIn('[data-test-input="publicKey"]', PUB_KEY);
diff --git a/ui/tests/helpers/openapi/expected-secret-attrs.js b/ui/tests/helpers/openapi/expected-secret-attrs.js
index 73ef2955d9c8..20aec8e5ae50 100644
--- a/ui/tests/helpers/openapi/expected-secret-attrs.js
+++ b/ui/tests/helpers/openapi/expected-secret-attrs.js
@@ -34,6 +34,13 @@ const ssh = {
fieldGroup: 'default',
type: 'boolean',
},
+ allowEmptyPrincipals: {
+ editType: 'boolean',
+ fieldGroup: 'default',
+ helpText:
+ 'Whether to allow issuing certificates with no valid principals (meaning any valid principal). Exists for backwards compatibility only, the default of false is highly recommended.',
+ type: 'boolean',
+ },
allowHostCertificates: {
editType: 'boolean',
helpText: