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: