Skip to content

Commit

Permalink
feat: improve redactions (#3647)
Browse files Browse the repository at this point in the history
Fixes #3641
  • Loading branch information
jdx authored Dec 17, 2024
1 parent ec9e03f commit 4ed4f02
Show file tree
Hide file tree
Showing 14 changed files with 313 additions and 137 deletions.
12 changes: 11 additions & 1 deletion docs/environments/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,17 @@ tools. To do that, turn the value into a map with `tools = true`:
```toml
[env]
MY_VAR = { value = "tools path: {{env.PATH}}", tools = true }
_.path = { value = ["{{env.GEM_HOME}}/bin"], tools = true } # directives may also set tools = true
_.path = { path = ["{{env.GEM_HOME}}/bin"], tools = true } # directives may also set tools = true
```

## Redactions

Variables can be redacted from the output by setting `redact = true`:

```toml
[env]
SECRET = { value = "my_secret", redact = true }
_.file = { path = [".env.json"], tools = true } # directives may also set redact = true
```

## `env._` directives
Expand Down
31 changes: 4 additions & 27 deletions docs/tasks/task-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,47 +321,24 @@ run = "echo task4"

If you want auto-completion/validation in included toml tasks files, you can use the following JSON schema: <https://mise.jdx.dev/schema/mise-task.json>

## `[redactions]` options
## `redactions`

- **Type**: `string[]`

Redactions are a way to hide sensitive information from the output of tasks. This is useful for things like
API keys, passwords, or other sensitive information that you don't want to accidentally leak in logs or
other output.

### `redactions.env`

- **Type**: `string[]`

A list of environment variables to redact from the output.

```toml
[redactions]
env = ["API_KEY", "PASSWORD"]
[tasks.test]
run = "echo $API_KEY"
redactions = ["API_KEY", "PASSWORD"]
```

Running the above task will output `echo [redacted]` instead.

You can also specify these as a glob pattern, e.g.: `redactions.env = ["SECRETS_*"]`.

### `redactions.vars`

- **Type**: `string[]`

A list of [vars](#vars) to redact from the output.

```toml
[vars]
secret = "mysecret"
[tasks.test]
run = "echo {{vars.secret}}"
```

:::tip
This is generally useful when using `mise.local.toml` to put secret vars in which can be shared
with any other `mise.toml` file in the hierarchy.
:::

## `[vars]` options

Vars are variables that can be shared between tasks like environment variables but they are not
Expand Down
29 changes: 20 additions & 9 deletions e2e/tasks/test_task_redactions
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
#!/usr/bin/env bash

cat <<EOF >mise.toml
redactions = ["SECRET"]
[env]
SECRET = "my_secret"
[tasks.a]
run = 'echo secret: \$SECRET'
[redactions]
env = ["SECRET"]
EOF

assert "mise run a" "secret: [redacted]"

cat <<EOF >mise.toml
redactions = ["secret"]
[tasks.a]
run = 'echo secret: {{ vars.secret }}'
[redactions]
vars = ["secret"]
[vars]
secret = "my_secret"
EOF

assert "mise run a" "secret: [redacted]"

cat <<EOF >mise.toml
redactions = ["SECRET*"]
[env]
SECRET_FOO = "my_secret_wild"
[tasks.a]
run = 'echo secret: \$SECRET_FOO'
EOF
assert "mise run a" "secret: [redacted]"

[redactions]
env = ["SECRET*"]
cat <<EOF >mise.toml
[env]
SECRET= {value = "my_secret", redact = true}
[tasks.a]
run = 'echo secret: \$SECRET'
EOF
assert "mise run a" "secret: [redacted]"

echo '{ "SECRET": "my_secret" }' >.env.json
cat <<EOF >mise.toml
[env]
_.file = {path = ".env.json", redact = true}
[tasks.a]
run = 'echo secret: \$SECRET'
EOF
assert "mise run a" "secret: [redacted]"
108 changes: 107 additions & 1 deletion schema/mise.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,39 @@
"env": {
"additionalProperties": {
"oneOf": [
{
"type": "object",
"properties": {
"value": {
"oneOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
}
]
},
"tools": {
"type": "boolean",
"description": "load tools before resolving"
},
"redact": {
"type": "boolean",
"description": "redact the value from logs"
}
}
},
{
"type": "string"
},
{
"type": "number"
},
{
"enum": [false],
"type": "boolean"
}
]
Expand All @@ -27,6 +52,32 @@
"properties": {
"file": {
"oneOf": [
{
"type": "object",
"properties": {
"path": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"tools": {
"type": "boolean",
"description": "load tools before resolving"
},
"redact": {
"type": "boolean",
"description": "redact the value from logs"
}
}
},
{
"description": "dotenv file to load",
"type": "string"
Expand All @@ -43,6 +94,28 @@
},
"path": {
"oneOf": [
{
"type": "object",
"properties": {
"path": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"redact": {
"type": "boolean",
"description": "redact the value from logs"
}
}
},
{
"description": "PATH entry to add",
"type": "string"
Expand Down Expand Up @@ -101,6 +174,32 @@
},
"source": {
"oneOf": [
{
"type": "object",
"properties": {
"path": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"tools": {
"type": "boolean",
"description": "load tools before resolving"
},
"redact": {
"type": "boolean",
"description": "redact the value from logs"
}
}
},
{
"description": "bash script to load",
"type": "string"
Expand Down Expand Up @@ -1249,6 +1348,13 @@
"pattern": "^\\d+\\.\\d+\\.\\d+$",
"type": "string"
},
"redactions": {
"description": "env or vars keys to redact from logs",
"type": "array",
"items": {
"type": "string"
}
},
"plugins": {
"additionalProperties": {
"description": "url to plugin repository",
Expand Down
9 changes: 5 additions & 4 deletions src/cli/run.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::{BTreeMap, HashSet};
use std::io::Write;
use std::iter::once;
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::process::Stdio;
use std::sync::Mutex;
Expand Down Expand Up @@ -380,7 +381,7 @@ impl Run {
.bright()
.to_string();
if !self.quiet(Some(task)) {
let msg = format!("{prefix} {}", config.redact(cmd)?);
let msg = format!("{prefix} {}", config.redact(cmd));
eprintln!("{}", trunc(&msg));
}

Expand Down Expand Up @@ -481,7 +482,7 @@ impl Run {
if !self.quiet(Some(task)) {
let cmd = format!("{} {}", display_path(file), args.join(" "));
let cmd = style::ebold(format!("$ {cmd}")).bright().to_string();
let cmd = trunc(&format!("{prefix} {}", config.redact(cmd)?));
let cmd = trunc(&format!("{prefix} {}", config.redact(cmd)));
eprintln!("{cmd}");
}

Expand Down Expand Up @@ -510,11 +511,11 @@ impl Run {
) -> Result<()> {
let config = Config::get();
let program = program.to_executable();
let redactions = config.redactions()?;
let redactions = config.redactions();
let mut cmd = CmdLineRunner::new(program.clone())
.args(args)
.envs(env)
.redact(redactions.clone())
.redact(redactions.deref().clone())
.raw(self.raw(Some(task)));
cmd.with_pass_signals();
match self.output(Some(task)) {
Expand Down
Loading

0 comments on commit 4ed4f02

Please sign in to comment.