Runbook: Team Setup & Member Management

Example 1. Purpose

Step-by-step runbook for creating teams, adding members, and managing shared secrets using dsec SOPS integration.

1. Prerequisites Checklist

Requirement Status Verification Command

SOPS installed

CHECK

sops --version (expect 3.x)

yq v4+ installed (Go version)

CHECK

yq --version (expect 4.x)

age installed

CHECK

age --version

dsec v2.0.0+

CHECK

dsec version

Master age key exists

CHECK

ls ~/.secrets/.metadata/keys/master.age.key

shared/ directory exists

CHECK

ls ~/.secrets/shared/

2. Phase 1: Verify Prerequisites

2.1. 1.1 Check SOPS Installation

sops --version

Expected: sops 3.x.x

If missing:

sudo pacman -S sops

2.2. 1.2 Check yq Installation

yq --version

Expected: yq (github.com/mikefarah/yq/) version v4.x.x

Must be Go yq (mikefarah/yq), not Python yq. If you see yq 3.x, install Go version:

sudo pacman -S go-yq

2.3. 1.3 Verify dsec SOPS Commands

dsec team help
dsec shared help
dsec cicd help

Expected: Help text for each subcommand

3. Phase 2: Create Team

3.1. 2.1 Initialize Team

# Syntax: dsec team init <team-id> [friendly-name]
dsec team init family "Family Home Automation"

Expected output:

✓ Created team: family
  Add members: dsec team add-member family <pubkey-file> --name <name>

3.2. 2.2 Verify Team Created

dsec team list

Expected:

╭── Teams (1) ───────────────────────────────────────────╮
│  family: Family Home Automation
│    1 member · 0 secrets · 2026-01-29
╰──────────────────────────────────────────────────────╯

3.3. 2.3 Check Directory Structure

tree -a ~/.secrets/shared/teams/family/

Expected:

~/.secrets/shared/teams/family/
└── .sops.yaml

4. Phase 3: Add Team Members

4.1. 3.1 Receive Member’s Public Key

The team member generates their key pair:

# ON MEMBER'S MACHINE
age-keygen -o ~/.age/private.key
age-keygen -y ~/.age/private.key > ~/my-public-key.txt

# They send you my-public-key.txt (safe to share)

4.2. 3.2 Add Member to Team

# Save their public key
cat > /tmp/alice.pub << 'EOF'
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
EOF

# Add to team
dsec team add-member family /tmp/alice.pub --name "Alice"

# Cleanup
shred -u /tmp/alice.pub

Expected output:

✓ Added member 'alice' to team 'family'
! Existing secrets must be re-encrypted: dsec team rotate family

4.3. 3.3 Verify Member Added

dsec team keys family

Expected:

╭── Team: family ──────────────────────────────────────────────────╮
  owner: age1wtdeuelfua4afrqqtw8claqf5wc335g7euhgh22pjzd57azpgq3q7jqcnn
  alice: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
╰────────────────────────────────────────────────────────────────╯

4.4. 3.4 Rotate Existing Secrets

After adding a member, existing secrets must be re-encrypted to include the new key.

dsec team rotate family

Expected:

→ Rotating secrets for team: family
✓ Rotated 0 secret file(s)

5. Phase 4: Create Shared Secrets

5.1. 4.1 Create Secret via Editor

dsec shared edit family home-automation

This opens your $EDITOR with SOPS. Add YAML content:

# Home automation secrets
MQTT_HOST: mqtt.home.local
MQTT_USER: homeassistant
MQTT_PASS: your-mqtt-password
ZIGBEE_NETWORK_KEY: "0x01030507090b0d0f00020406080a0c0e"
HASS_TOKEN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Save and exit. SOPS encrypts automatically.

5.2. 4.2 Verify Secret Created

dsec shared list family

Expected:

╭── Shared Secrets ──────────────────────────────────────╮
│  family/
│    home-automation
╰──────────────────────────────────────────────────────╯

5.3. 4.3 View Decrypted Secret

dsec shared show family home-automation

Expected: Your YAML content displayed

5.4. 4.4 Load to Environment

# Using wrapper
dsteam family home-automation

# Verify loaded
env | grep MQTT

# Clear when done
dsteunsource

6. Phase 5: Member Access Verification

6.1. 5.1 Member Decryption Test

The team member verifies access on their machine:

# ON MEMBER'S MACHINE

# Set their key
export SOPS_AGE_KEY_FILE=~/.age/private.key

# Decrypt (assuming they have access to the file)
sops -d ~/.secrets/shared/teams/family/home-automation.yaml

Expected: Decrypted YAML content

7. Validation Summary

After completing all steps, verify:

Check Status Command

Team exists in registry

VERIFY

dsec team list

Team has correct members

VERIFY

dsec team keys <team>

Secrets created

VERIFY

dsec shared list <team>

Secrets decrypt correctly

VERIFY

dsec shared show <team> <name>

Environment load works

VERIFY

dsteam <team> <name> && env | grep KEY

Member can decrypt

VERIFY

Member runs sops -d with their key

8. Removing Team Members

8.1. Remove Member

dsec team remove-member family alice

8.2. Rotate Secrets (Critical!)

After removing a member, always rotate secrets and consider changing any credentials they had access to.

# Re-encrypt without removed member
dsec team rotate family

# Additionally, change actual credentials:
# - Rotate MQTT password
# - Regenerate API tokens
# - Update Zigbee network key if concerned

9. Troubleshooting

Issue Cause Solution

yq v4+ required

Wrong yq version

sudo pacman -S go-yq

Team not found

Typo or not created

dsec team list then dsec team init

Failed to decrypt

Wrong age key

Verify SOPS_AGE_KEY_FILE path

Member can’t decrypt

Not in recipients

dsec team rotate after adding