Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/dependabot-automerge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ name: Dependabot auto-merge

on: pull_request

permissions:
contents: write
pull-requests: write
permissions: read-all

jobs:
auto-merge:
if: github.actor == 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Fetch Dependabot metadata
id: meta
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Lint
working-directory: node
run: |
npm install
npm ci
npx biome check

test:
Expand All @@ -45,7 +45,7 @@ jobs:
- name: Install and test
working-directory: node
run: |
npm install
npm ci
npx napi build --platform --release
node __test__/index.test.mjs

Expand Down Expand Up @@ -89,7 +89,7 @@ jobs:

- name: Install dependencies
working-directory: node
run: npm install
run: npm ci

- name: Build (native)
if: ${{ !matrix.settings.docker }}
Expand Down Expand Up @@ -142,7 +142,7 @@ jobs:
- name: Publish
working-directory: node
run: |
npm install
npm ci
npx napi prepublish -t npm --skip-gh-release
npm publish --access public --provenance
env:
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ tempfile = "3.27.0"
clap_complete = "4.6.0"
fs2 = "0.4.3"
pyo3 = { version = "0.28", features = ["extension-module"], optional = true }
walkdir = "2.5.0"

[target.'cfg(unix)'.dependencies]
libc = "0.2"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,15 @@ murk restore
| `murk edit [KEY] [--scoped]` | Edit secrets in `$EDITOR` |
| `murk ls` | List key names |
| `murk export` | Print all secrets as shell exports |
| `murk exec CMD...` | Run a command with secrets in the environment |
| `murk exec CMD...` | Run a command with secrets in the environment (`--only`, `--clean-env`) |
| `murk diff [REF]` | Show secret changes since a git ref |
| `murk import [FILE]` | Import secrets from a .env file |
| `murk describe KEY "..."` | Set description for a key |
| `murk info` | Show public schema (no key required) |
| `murk circle` | List recipients |
| `murk circle authorize PUBKEY [--name NAME]` | Add a recipient (age key, `ssh:path`, or `github:user`) |
| `murk circle revoke RECIPIENT` | Remove a recipient |
| `murk scan [PATHS...]` | Scan files for leaked secret values |
| `murk skeleton` | Export schema-only vault with no secrets or recipients |
| `murk restore` | Recover key from BIP39 phrase |
| `murk recover` | Show recovery phrase for current key |
Expand Down
69 changes: 69 additions & 0 deletions docs/quick-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Quick start for teammates

You've been invited to a project that uses murk for secrets. Here's how to get set up.

## 1. Install murk

```bash
brew tap iicky/murk && brew install murk
```

Or: `cargo install murk-cli`, `pip install murk`, or download from [GitHub Releases](https://github.com/iicky/murk/releases).

## 2. Generate your key

```bash
murk init
```

This creates your keypair and prints 24 recovery words. **Write them down.** If you lose your key, these words are the only way to recover it.

Your key is stored in `~/.config/murk/keys/`, not in the repo.

## 3. Share your public key

```bash
murk recover
```

Wait — that's for recovery. To get your public key for authorization:

```bash
cat ~/.config/murk/keys/*.pub 2>/dev/null || murk info 2>/dev/null
```

Actually, the easiest path: ask the team lead to run:

```bash
murk circle authorize github:YOUR_USERNAME
```

This fetches your SSH public keys from GitHub and adds you to the vault. No manual key exchange needed.

## 4. Pull and use secrets

Once authorized:

```bash
git pull # get the updated .murk file
murk ls # see what secrets are available
murk get DATABASE_URL # print one secret
murk export # print all as shell exports
murk exec -- ./my-script.sh # run a command with secrets in env
```

## 5. Set up direnv (optional)

```bash
murk env
direnv allow
```

Now secrets are automatically loaded when you `cd` into the project.

## What to know

- **Key names are public.** Anyone with repo access can see what secrets exist (e.g. `STRIPE_KEY`). Only values are encrypted.
- **Your key is your identity.** Don't share it. Don't paste it into chat. Don't commit it.
- **Recovery phrase = your key.** If someone has your 24 words, they have your key.
- **Revocation doesn't erase history.** If you leave the team, your access to old git history remains. The team should rotate secrets after revoking you.
13 changes: 13 additions & 0 deletions src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec![],
..Default::default()
},
);

Expand All @@ -235,6 +236,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec![],
..Default::default()
},
);

Expand All @@ -257,6 +259,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec!["db".into()],
..Default::default()
},
);
vault.schema.insert(
Expand All @@ -265,6 +268,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec!["api".into()],
..Default::default()
},
);

Expand All @@ -286,6 +290,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec![],
..Default::default()
},
);

Expand Down Expand Up @@ -435,6 +440,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec![],
..Default::default()
},
);

Expand All @@ -455,6 +461,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec![],
..Default::default()
},
);

Expand All @@ -474,6 +481,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec![],
..Default::default()
},
);

Expand All @@ -496,6 +504,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec!["db".into()],
..Default::default()
},
);
vault.schema.insert(
Expand All @@ -504,6 +513,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec!["api".into()],
..Default::default()
},
);

Expand All @@ -526,6 +536,7 @@ mod tests {
description: "orphan key".into(),
example: None,
tags: vec!["db".into()],
..Default::default()
},
);
vault.schema.insert(
Expand All @@ -534,6 +545,7 @@ mod tests {
description: "has a value".into(),
example: None,
tags: vec!["db".into()],
..Default::default()
},
);

Expand All @@ -558,6 +570,7 @@ mod tests {
description: String::new(),
example: None,
tags: vec![],
..Default::default()
},
);

Expand Down
3 changes: 3 additions & 0 deletions src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ mod tests {
description: "database url".into(),
example: Some("postgres://...".into()),
tags: vec!["db".into()],
..Default::default()
},
);
let bytes = test_vault_bytes(schema);
Expand All @@ -265,6 +266,7 @@ mod tests {
description: "db".into(),
example: None,
tags: vec!["db".into()],
..Default::default()
},
);
schema.insert(
Expand All @@ -273,6 +275,7 @@ mod tests {
description: "api".into(),
example: None,
tags: vec!["api".into()],
..Default::default()
},
);
let bytes = test_vault_bytes(schema);
Expand Down
Loading
Loading