-
Notifications
You must be signed in to change notification settings - Fork 52
(SCHEMA) Add extension secret to schema source #1083
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Gijsreyn
wants to merge
4
commits into
PowerShell:main
Choose a base branch
from
Gijsreyn:add-secret-schema
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
b93ae0d
Add schema for secret
Gijsreyn 228273a
Add rewritten version Mikey
Gijsreyn 662a762
(SCHEMA) Enhance docs and validation for `secret` in extension manife…
michaeltlombardi df3d6b5
(SCHEMA) Update docs keywords for `secret` operation stdout schema
michaeltlombardi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,305 @@ | ||
# yaml-language-server: $schema=https://json-schema.org/draft/2020-12/schema | ||
$schema: https://json-schema.org/draft/2020-12/schema | ||
$id: <HOST>/<PREFIX>/<VERSION>/extension/manifest.secret.yaml | ||
|
||
title: Secret operation command | ||
description: >- | ||
Defines how DSC must call the DSC extension to retrieve a secret value. | ||
markdownDescription: | # VS Code only | ||
*** | ||
[_Online Documentation_][00] | ||
*** | ||
|
||
Defines how DSC must call the DSC extension to retrieve a secret value. An extension that defines | ||
this field in its manifest has the `secret` capability. | ||
|
||
DSC expects extensions implementing the `secret` capability to adhere to the following contract: | ||
|
||
1. If the extension retrieves the secret, the extension must emit the secret to stdout as a | ||
single line of plaintext and exit with code `0`. DSC consumes the emitted output and makes the | ||
secret available in the configuration document. | ||
|
||
If the extension emits more than one line to stdout, DSC raises an error. | ||
|
||
1. If the extension cannot retrieve the secret because the secret doesn't exist, the extension | ||
must not emit any text to stdout and must exit with code `0`. DSC interprets this result as | ||
the secret not existing in the vault. | ||
|
||
1. If the extension cannot retrieve the secret for any other reason, such as invalid credentials | ||
or an API error, the extension should emit a descriptive error message as a JSON Line to | ||
stderr and exit with a nonzero exit code. DSC interprets the nonzero exit code as an | ||
operational failure and surfaces that information and any emitted error messages to the user. | ||
|
||
When the exit code for the operation is `0`, DSC interprets the operation as completing without | ||
errors. For extensions, failure to retrieve a secret because it doesn't exist is _not_ an error. | ||
Failure to retrieve a secret for any other reason _is_ an error and the extension should exit | ||
with a nonzero code. For an improved user experience, the extension should define the `exitCodes` | ||
field in the extension manifest to indicate what the nonzero exit code means. | ||
|
||
For more information about how DSC validates the data for stdout, see | ||
[Secret extension operation stdout][01]. For more information about defining exit codes for the | ||
extension, see [`exitCodes`][02] in the extension manifest schema reference. | ||
|
||
[00]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN> | ||
[01]: <DOCS_BASE_URL>/reference/schemas/extension/stdout/secret?<DOCS_VERSION_PIN> | ||
[02]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/root?<DOCS_VERSION_PIN>#exitcodes | ||
|
||
type: object | ||
required: | ||
- executable | ||
- args | ||
properties: | ||
executable: | ||
$ref: /<PREFIX>/<VERSION>/definitions/commandExecutable.yaml | ||
markdownDescription: | | ||
*** | ||
[_Online Documentation_][00] | ||
*** | ||
|
||
Defines the name of the command to run. The value must be the name of a command discoverable | ||
in the system's `PATH` environment variable or the full path to the command. A file extension | ||
is only required when the command isn't recognizable by the operating system as an | ||
executable. | ||
|
||
[00]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN>#executable | ||
args: | ||
title: Arguments | ||
description: >- | ||
Defines an ordered list of arguments to pass to the command. | ||
markdownDescription: | | ||
*** | ||
[_Online Documentation_][00] | ||
*** | ||
|
||
Defines an ordered list of arguments to pass to the command. DSC passes each defined item to | ||
the executable in the order you define them. Items can be string arguments, the secret name | ||
input argument, or the vault input argument. | ||
|
||
In order for DSC to retrieve a secret with the extension, the manifest must define the secret | ||
name input argument. For DSC to retreieve a secret from a specific vault with the extension, | ||
the manifest must define the vault input argument. | ||
|
||
For example, given the following manifest snippet: | ||
|
||
```jsonc | ||
{ | ||
// ellided extension manifest fields | ||
"secret": { | ||
"executable": "my_secret_extension", | ||
"args": [ | ||
"get", | ||
{ "nameArg": "--secretName" } | ||
] | ||
} | ||
} | ||
``` | ||
|
||
When DSC invokes the extension to retrieve a secret named `apiToken`, it constructs | ||
the following effective command: | ||
|
||
```bash | ||
my_secret_extension get --secretName apiToken | ||
``` | ||
|
||
If the user needs to retrieve a secret from a specific vault, DSC is unable to pass the vault | ||
name to the previously defined snippet. The following snippet supports passing the vault name | ||
to the extension as well as the secret name: | ||
|
||
```jsonc | ||
{ | ||
// ellided extension manifest fields | ||
"secret": { | ||
"executable": "my_secret_extension", | ||
"args": [ | ||
"get", | ||
{ "nameArg": "--secretName" }, | ||
{ "vaultArg": "--vaultName" } | ||
] | ||
} | ||
} | ||
``` | ||
|
||
When DSC invokes the extension to retrieve a secret named `apiToken` from the `services` | ||
vault, it constructs the following effective command: | ||
|
||
```bash | ||
my_secret_extension get --secretName apiToken --vaultName services | ||
``` | ||
|
||
[00]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN>#args | ||
type: array | ||
items: | ||
oneOf: | ||
- title: String argument | ||
description: >- | ||
Any item in the argument array can be a string representing a static argument to pass | ||
to the command, like `get` or `--quiet`. | ||
markdownDescription: |- | ||
*** | ||
[_Online Documentation_][00] | ||
*** | ||
|
||
Any item in the argument array can be a string representing a static argument to pass | ||
to the command, like `get` or `--quiet`. | ||
|
||
[00]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN>#string-arguments | ||
type: string | ||
minLength: 1 | ||
- type: object | ||
title: Secret name input argument | ||
description: >- | ||
Defines the argument for the command that accepts the name of a secret. | ||
markdownDescription: |- | ||
*** | ||
[_Online Documentation_][00] | ||
*** | ||
|
||
Defines the argument for the command that accepts the name of a secret. DSC passes the | ||
name of the secret as a string after the defined argument. You must define this | ||
argument as an object with the `nameArg` property set to the appropriate argument for | ||
the extension command, like `--secret` or `--secret-name`. | ||
|
||
An extension implementing the `secret` capability _must_ define a secret name input | ||
argument exactly once. | ||
|
||
[00]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN>#secret-name-input-argument | ||
unevaluatedProperties: false | ||
required: | ||
- nameArg | ||
properties: | ||
nameArg: | ||
title: Secret name input argument definition | ||
description: >- | ||
Defines the literal string for the argument that accepts the name of the secret to | ||
retrieve, like `--name` or `--secret-name`. | ||
markdownDescription: |- | ||
Defines the literal string for the argument that accepts the name of the secret to | ||
retrieve, like `--name` or `--secret-name`. | ||
type: string | ||
minLength: 1 | ||
- type: object | ||
title: Vault input argument | ||
description: >- | ||
Defines the argument for the command that accepts the name of a specific vault to | ||
retrieve a secret from. | ||
markdownDescription: |- | ||
*** | ||
[_Online Documentation_][00] | ||
*** | ||
|
||
Defines the argument for the command that accepts the name of a specific vault to | ||
retrieve a secret from. Define this argument as an object with the `vaultArg` property | ||
set to the appropriate argument for the extension command, like `--vault` or | ||
`--vault-name`. | ||
|
||
To support retrieving secrets from a specific vault, an extension implementing the | ||
`secret` capability _must_ define a vault input argument exactly once. | ||
|
||
[00]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN>#vault-input-argument | ||
unevaluatedProperties: false | ||
required: | ||
- vaultArg | ||
properties: | ||
vaultArg: | ||
title: Vault input argument definition | ||
description: >- | ||
Defines the literal string for the argument that accepts the name of the vault to | ||
retrieve a secret from, like `--vault` or `--vault-name`. | ||
markdownDescription: |- | ||
Defines the literal string for the argument that accepts the name of the vault to | ||
retrieve a secret from, like `--vault` or `--vault-name`. | ||
type: string | ||
minLength: 1 | ||
|
||
# Need to use an allOf with multiple possibilities to capture the requirement to define the secret | ||
# name input argument exactly once and the vault input argument no more than once. Note that | ||
# the YAML language server in VS Code currently doesn't understand the `minContains` and | ||
# `maxContains` keywords, so when defining the extension manifest in YAML with the schema, the | ||
# language server identifies the vault input argument as required. When defining the extension | ||
# manifest in JSON, the language server correctly identifies the minimum and maximum number of | ||
# arguments to use. | ||
# | ||
# Unfortunately, because we only get one error message per item in the `allOf` keyword, we have to | ||
# define two entries for the secret name input argument to provide better validation error messages. | ||
# | ||
# We use long lines for error messages, which can't use Markdown, so line breaks are literal. | ||
allOf: | ||
- title: Missing secret name input argument | ||
$comment: >- | ||
This validation subschema ensures that `secret.args` contains a secret name input argument. | ||
Without this argument, DSC can't pass the name of the secret to retrieve when invoking the | ||
extension's secret command. | ||
|
||
We define this separately from the maximum contains validation subschema to improve the error | ||
messaging in VS Code. | ||
properties: | ||
args: | ||
errorMessage: |- | ||
The `secret` command doesn't define the secret name input argument. If you don't define the secret name input argument, DSC can't pass the secret name to the extension for retrieval. You can only define one secret name input argument for the command. | ||
|
||
You must define one argument in `secret.args` as a JSON object with the `nameArg` property. For more information, see: | ||
|
||
<DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN> | ||
contains: | ||
type: object | ||
required: [nameArg] | ||
minContains: 1 | ||
- title: Multiple secret name input arguments | ||
$comment: >- | ||
This validation subschema ensures that `secret.args` doesn't contain more than one secret | ||
name input argument. Defining more than one secret name input argument is invalid. | ||
|
||
We define this separately from the minimum contains validation subschema to improve the error | ||
messaging in VS Code. | ||
properties: | ||
args: | ||
errorMessage: |- | ||
The `secret` command defines the secret name input argument more than once. You can only define one secret name input argument for the command. | ||
|
||
You must define one argument in `secret.args` as a JSON object with the `nameArg` property and remove the additional secret name input arguments. For more information, see: | ||
|
||
<DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN> | ||
contains: | ||
type: object | ||
required: [nameArg] | ||
maxContains: 1 | ||
- title: Multiple vault input arguments | ||
$comment: >- | ||
This validation subschema ensures that `secret.args` contains zero or one vault input | ||
arguments. Defining a vault input argument is optional. Extensions that don't define the | ||
vault input argument don't support retrieving secrets from a specific vault. Defining | ||
more than one vault input argument is invalid. | ||
properties: | ||
args: | ||
errorMessage: |- | ||
The `secret` command defines the vault input argument more than once. If you don't define the vault input argument, DSC can't pass the vault to the extension for retrieving a secret from a specific vault. You can only define one vault input argument for the command. | ||
|
||
You can define one argument in `secret.args` as a JSON object with the `vaultArg` property. For more information, see: | ||
|
||
<DOCS_BASE_URL>/reference/schemas/extension/manifest/secret?<DOCS_VERSION_PIN> | ||
contains: | ||
type: object | ||
required: [vaultArg] | ||
minContains: 0 | ||
maxContains: 1 | ||
|
||
defaultSnippets: # VS Code only | ||
- label: ' Define with arguments (static string and secret name input arguments)' | ||
markdownDescription: |- | ||
Define the `secret` command where the secret name is passed to the command. Use this | ||
snippet if the extension doesn't support retrieving a secret from a specific vault. | ||
body: | ||
executable: ${1:executable_name} | ||
args: | ||
- ${2:get} | ||
- nameArg: ${3:--secret-name} | ||
- label: ' Define with arguments (static string, secret name, and vault input arguments)' | ||
markdownDescription: |- | ||
Define the `secret` command where both the secret name and the vault name are passed to the | ||
command. Use this snippet if the extension supports retrieving a secret from a specific vault. | ||
body: | ||
executable: ${1:executable_name} | ||
args: | ||
- ${2:get} | ||
- nameArg: ${3:--secret-name} | ||
- vaultArg: ${4:--vault-name} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# yaml-language-server: $schema=https://json-schema.org/draft/2020-12/schema | ||
$schema: https://json-schema.org/draft/2020-12/schema | ||
$id: <HOST>/<PREFIX>/<VERSION>/extension/stdout/secret.yaml | ||
|
||
title: Secret extension operation stdout | ||
description: >- | ||
Represents the secret text returned by a DSC extension for a secret request. | ||
markdownDescription: | # VS Code only | ||
*** | ||
[_Online Documentation_][00] | ||
*** | ||
|
||
Represents the secret text returned by a DSC extension for a secret request. The output that | ||
DSC expects from the extension depends on the result of retrieving the secret: | ||
|
||
- If the extension successfully retrieves the secret, DSC expects the extension to: | ||
|
||
1. Emit a single line containing only the secret value, not wrapped in quotation marks or a | ||
JSON object, to stdout. DSC treats the literal text returned by the extension as the secret | ||
value. If the emitted output contains any newlines, the output is invalid. | ||
1. Exit with code `0` to indicate success. | ||
|
||
- If the extension can't retrieve the secret because no secret with the given name was | ||
discovered, DSC expects the extension to: | ||
|
||
1. Emit _no output_ to stdout. If the extension emits any output to stdout, DSC interprets the | ||
emitted text to be the secret value. | ||
1. Optionally emit messages to stderr as [JSON Lines][01] to indicate the attempt to retrieve | ||
the secret and noting that the secret doesn't exist. DSC surfaces emitted messages to the | ||
caller depending on the message level. | ||
1. Exit with code `0` to indicate success. For DSC, an extension not returning a secret value | ||
because no secret with the given name exists is _not_ a failure. | ||
|
||
- If the extension can't retrieve the secret for any other reason, such as requiring the vault | ||
to be unlocked or encountering an API error, DSC expects the extension to: | ||
|
||
1. Emit _no output_ to stdout. | ||
1. Optionally emit detailed error messages to stderr as [JSON Lines][01] to provide contextual | ||
information about how and why the retrieval failed. DSC always surfaces emitted error | ||
messages to the caller. | ||
1. Exit with a nonzero code to indicate failure. If the extension manifest defines the | ||
[`exitCodes`][02] field, DSC surfaces the meaning of the exit code to the caller. | ||
|
||
[00]: <DOCS_BASE_URL>/reference/schemas/extension/stdout/secret?<DOCS_VERSION_PIN> | ||
[01]: https://jsonlines.org/ | ||
[02]: <DOCS_BASE_URL>/reference/schemas/extension/manifest/root?<DOCS_VERSION_PIN>#exitcodes | ||
|
||
type: string | ||
minLength: 0 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.