Secrets & Security
Vault access, secret generation, hashing, encryption and certificates. Every parameter with its type, default and description, plus worked examples.
Platform-integrated secret management using HashiCorp Vault with mTLS authentication.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
operation | string | No | read | Operation: read, get, write, set |
url | string | Yes | - | Vault server URL |
cluster | string | Yes | - | Cluster name |
datacenter | string | Yes | - | Datacenter name |
workspace | string | Yes | - | Workspace/environment name |
customer | string | Yes | - | Customer identifier |
forgeslug | string | Yes | - | Forge/product slug |
productiondomain | string | Yes | - | Tenant domain |
certificate | string | Yes | - | TLS certificate for authentication |
key | string | Yes | - | TLS private key for authentication |
issuer | list | Yes | - | Certificate issuers |
secretname | string | Yes | - | Name of the secret to read/write |
secretvalue | string | No | - | Value to write (required for write) |
service | string | No | vulcan | Service name |
setvar | string | No | - | Variable to store result |
Examples
Section titled “Examples”Read Secret
Section titled “Read Secret”name: vault-readvars: vault_url: "{{env.VAULT_URL}}" cluster: production datacenter: us-east-1tasks: - name: get-db-password vault: operation: read url: "{{vault_url}}" cluster: "{{cluster}}" datacenter: "{{datacenter}}" workspace: production customer: acme forgeslug: webapp productiondomain: acme.example.com certificate: "{{tls_cert}}" key: "{{tls_key}}" issuer: - "{{ca_cert}}" secretname: database-password setvar: db_passwordWrite Secret
Section titled “Write Secret”name: vault-writetasks: - name: store-api-key vault: operation: write url: "{{vault_url}}" cluster: "{{cluster}}" datacenter: "{{datacenter}}" workspace: production customer: acme forgeslug: webapp productiondomain: acme.example.com certificate: "{{tls_cert}}" key: "{{tls_key}}" issuer: - "{{ca_cert}}" secretname: api-key secretvalue: "{{generated_key}}"See Also: Vault Script Namespace
Section titled “See Also: Vault Script Namespace”For simpler vault access from scripts, use the vault namespace instead of the vault task. The namespace uses the service’s pre-initialized vault client, requiring only a secret name — no TLS, datacenter, or cluster params needed:
- name: get-secret script: namespaces: http,vault code: | var secret = vault.get("database-password"); vault.save({name: "new-key", value: "value123", indefinite: true});See vault namespace docs for full reference.
Secret
Section titled “Secret”Generate secrets, passwords, and passphrases.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
operation | string | No | generate | Operation: generate, encode, decode, hash |
setvar | string | Yes | - | Variable to store result |
length | int | No | 32 | Length of generated secret |
pattern | string | No | - | Predefined pattern (see below) |
words | int | No | - | Number of words for passphrase |
prefix | string | No | - | Prefix for generated secret |
separator | string | No | - | Word separator for passphrase |
uppercase | bool | No | true | Include uppercase letters |
lowercase | bool | No | true | Include lowercase letters |
digits | bool | No | true | Include digits |
special | bool | No | false | Include special characters |
charset | string | No | - | Custom character set |
hash | bool | No | false | Also generate bcrypt hash |
value | string | No | - | Input value for encode/decode/hash |
encoding | string | No | base64 | Encoding: base64, base64url, hex |
Patterns
Section titled “Patterns”| Pattern | Description |
|---|---|
alphanumeric | Letters and digits |
alpha | Letters only |
numeric | Digits only |
hex | Hexadecimal |
base64 | Base64-safe characters |
password | Strong password with all character types |
passphrase | Diceware word-based password |
pin | Numeric PIN |
uuid | UUID v4 format |
apikey | API key format (prefix_random) |
Examples
Section titled “Examples”Generate API Key
Section titled “Generate API Key”name: secret-apikeytasks: - name: generate secret: length: 32 setvar: api_keyGenerate Passphrase
Section titled “Generate Passphrase”name: secret-passphrasetasks: - name: generate secret: pattern: passphrase words: 4 setvar: memorable_password## Result: "correct-horse-battery-staple"Generate Password with Hash
Section titled “Generate Password with Hash”name: secret-passwordtasks: - name: generate secret: pattern: password length: 16 hash: true setvar: user_password## Result: {{user_password}} = "Kj#9mN$pL2@xQw4r"## {{user_password_hash}} = bcrypt hashAPI Key with Prefix
Section titled “API Key with Prefix”name: secret-prefixedtasks: - name: generate secret: pattern: apikey prefix: sk_live length: 32 setvar: stripe_key## Result: "sk_live_a1b2c3d4e5f6..."Base64 Encode
Section titled “Base64 Encode”name: secret-encodevars: username: admin password: secrettasks: - name: encode secret: operation: encode encoding: base64 value: "{{username}}:{{password}}" setvar: basic_authNamespace: secret
Section titled “Namespace: secret”Secret generation and encoding functions.
Functions
Section titled “Functions”| Function | Description |
|---|---|
secret.generate() | Generate random secrets/passwords |
secret.encode() | Encode data (base64, hex) |
secret.decode() | Decode encoded data |
secret.hash() | Hash value using bcrypt |
secret.validate() | Validate password strength |
Generate Parameters
Section titled “Generate Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
pattern | string | "alphanumeric" | Pattern: alphanumeric, hex, base64, passphrase |
length | int | 32 | Secret length |
prefix | string | - | Prefix to add |
uppercase | bool | false | Include uppercase |
lowercase | bool | false | Include lowercase |
digits | bool | false | Include digits |
special | bool | false | Include special chars |
charset | string | - | Custom character set |
hash | bool | false | Return bcrypt hash too |
separator | string | "-" | Word separator (passphrase) |
words | int | - | Word count (passphrase) |
Encode/Decode Parameters
Section titled “Encode/Decode Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
data | string | - | Data to encode/decode |
encoding | string | "base64" | Encoding: base64, base32, hex |
Examples
Section titled “Examples”// Generate API keylet key = secret.generate({ length: 32, pattern: "alphanumeric"})log("API Key:", key.secret)
// Generate passphraselet pass = secret.generate({ pattern: "passphrase", words: 4, separator: "-"})log("Passphrase:", pass.secret)
// Generate with hashlet pwd = secret.generate({ length: 16, special: true, hash: true})log("Password:", pwd.secret)log("Hash:", pwd.hash)
// Base64 encodelet encoded = secret.encode({ data: "admin:password", encoding: "base64"})log("Encoded:", encoded.encoded)
// Base64 decodelet decoded = secret.decode({ data: encoded.encoded, encoding: "base64"})log("Decoded:", decoded.decoded)
// Hash password (bcrypt)let hashed = secret.hash({ value: "mypassword"})log("Bcrypt hash:", hashed.hash)
// Validate password strengthlet valid = secret.validate({ value: "WeakPwd"})if (!valid.success) { log("Password too weak:", valid.error)}Encrypt/Decrypt
Section titled “Encrypt/Decrypt”File encryption using AES.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
secret | string | Yes | Encryption key (vault key) |
source | string | Yes | Source file path |
destination | string | Yes | Destination file path |
pattern | string | No | Glob pattern for multiple files |
Examples
Section titled “Examples”Encrypt File
Section titled “Encrypt File”name: encrypt-filetasks: - name: encrypt encrypt: secret: my-vault-key source: /data/file.txt destination: /data/file.encDecrypt File
Section titled “Decrypt File”name: decrypt-filetasks: - name: decrypt decrypt: secret: my-vault-key source: /data/file.enc destination: /data/file.txtNamespace: crypt
Section titled “Namespace: crypt”Encryption and decryption functions.
Functions
Section titled “Functions”| Function | Description |
|---|---|
crypt.encryptFile() | Encrypt a file |
crypt.decryptFile() | Decrypt a file |
crypt.encrypt() | Encrypt data in memory |
crypt.decrypt() | Decrypt data in memory |
File Parameters
Section titled “File Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
secret | string | - | Encryption key/passphrase |
source | string | - | Source file path |
destination | string | - | Destination file path |
algorithm | string | "aes-256-gcm" | Algorithm: aes-256-gcm, aes-256-cbc, aes-128-gcm |
overwrite | bool | false | Overwrite existing file |
iterations | int | 100000 | PBKDF2 iterations |
In-Memory Parameters
Section titled “In-Memory Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
secret | string | - | Encryption key/passphrase |
data | string | - | Data to encrypt/decrypt |
algorithm | string | "aes-256-gcm" | Algorithm |
iterations | int | 100000 | PBKDF2 iterations |
Examples
Section titled “Examples”// Encrypt filelet result = crypt.encryptFile({ secret: "my-secret-key", source: "/data/sensitive.txt", destination: "/data/sensitive.enc", algorithm: "aes-256-gcm"})log("Encrypted to:", result.destination)
// Decrypt filecrypt.decryptFile({ secret: "my-secret-key", source: "/data/sensitive.enc", destination: "/data/sensitive.txt", overwrite: true})
// Encrypt data in memory (returns base64)let encrypted = crypt.encrypt({ secret: "my-secret-key", data: "sensitive information"})log("Encrypted:", encrypted.encrypted)
// Decrypt data in memorylet decrypted = crypt.decrypt({ secret: "my-secret-key", data: encrypted.encrypted})log("Decrypted:", decrypted.decrypted)
// Higher security with more iterationscrypt.encryptFile({ secret: "my-secret-key", source: "/data/critical.txt", destination: "/data/critical.enc", iterations: 500000})Generate cryptographic hashes.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
value | string | No | - | String to hash |
file | string | No | - | File to hash |
algorithm | string | No | sha256 | Algorithm: sha256, sha512, sha1, md5 |
length | int | No | 0 | Truncate hash to N characters |
set | string | Yes | - | Variable to store hash |
Examples
Section titled “Examples”Hash a String
Section titled “Hash a String”name: hash-stringtasks: - name: hash hash: value: "hello world" algorithm: sha256 set: hash_resultHash a File
Section titled “Hash a File”name: hash-filetasks: - name: hash-file hash: file: /path/to/file.txt algorithm: sha256 set: file_hashNamespace: hash
Section titled “Namespace: hash”Cryptographic hashing functions.
Functions
Section titled “Functions”| Function | Description |
|---|---|
hash.string() | Hash a string value |
hash.file() | Hash a file |
hash.bytes() | Hash byte data |
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
data | string | - | Data to hash (for string/bytes) |
path | string | - | File path (for file) |
algorithm | string | "sha256" | Algorithm: sha256, sha512, sha1, md5, blake2b, xxhash |
length | int | 0 | Truncate hash to N characters (0 = full) |
Examples
Section titled “Examples”// Hash a stringlet result = hash.string({ data: "hello world", algorithm: "sha256"})log("Hash:", result.hash)
// Hash with truncationlet short = hash.string({ data: "hello world", algorithm: "sha256", length: 8})log("Short hash:", short.hash)
// Hash a filelet fileHash = hash.file({ path: "/path/to/file.txt", algorithm: "sha256"})log("File hash:", fileHash.hash)
// Different algorithmshash.string({ data: "test", algorithm: "md5" }) // MD5hash.string({ data: "test", algorithm: "sha512" }) // SHA-512hash.string({ data: "test", algorithm: "blake2b" }) // BLAKE2bhash.string({ data: "test", algorithm: "xxhash" }) // xxHash (fast)Generate unique identifiers (ULID, UUID, NanoID, KSUID, XID).
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | No | ulid | ID type (see below) |
setvar | string | Yes | - | Variable to store generated ID |
ID Types
Section titled “ID Types”| Type | Description |
|---|---|
ulid | ULID (uppercase) |
ulid-lower | ULID (lowercase) |
uuid | UUID v4 |
uuidv4 | UUID v4 |
uuidv6 | UUID v6 |
uuidv7 | UUID v7 |
uuidv1 | UUID v1 |
Examples
Section titled “Examples”Generate UUID v7
Section titled “Generate UUID v7”name: gen-idtasks: - name: create-id id: type: uuidv7 setvar: user_idGenerate ULID (Default)
Section titled “Generate ULID (Default)”name: gen-ulidtasks: - name: create-ulid id: setvar: request_idNamespace: id
Section titled “Namespace: id”Identifier generation functions (ULID, UUID).
Functions
Section titled “Functions”| Function | Description |
|---|---|
id.generate() | Generate unique identifier(s) |
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
type | string | "ulid" | ID type: ulid, uuid, nanoid, ksuid, xid |
count | int | 1 | Number of IDs to generate |
Examples
Section titled “Examples”// Generate single ULID (default)let result = id.generate({})log("ID:", result.id)
// Generate UUID v4let uuid = id.generate({ type: "uuid" })log("UUID:", uuid.id)
// Generate multiple IDslet ids = id.generate({ type: "nanoid", count: 5})log("Generated", ids.ids.length, "IDs")
// Available typesid.generate({ type: "ulid" }) // 01ARZ3NDEKTSV4RRFFQ69G5FAVid.generate({ type: "uuid" }) // f47ac10b-58cc-4372-a567-0e02b2c3d479id.generate({ type: "nanoid" }) // V1StGXR8_Z5jdHi6B-myTid.generate({ type: "ksuid" }) // 0ujsswThIGTUYm2K8FjOOfXtY1Kid.generate({ type: "xid" }) // 9m4e2mr0ui3e8a215n4gLetsencrypt
Section titled “Letsencrypt”ACME certificate management — issue, renew, revoke, read, list.
Default CA is Let’s Encrypt; the caURL parameter accepts any
ACME-compatible directory (ZeroSSL, step-ca, Buypass). Built on
certmagic — supports HTTP-01,
DNS-01, and TLS-ALPN-01 challenges. DNS-01 reuses the six libdns
providers wired into the dns task.
Replaces the old acme task
Section titled “Replaces the old acme task”This task replaces the lego-based acme task entirely. The old
acme:/legodns: names are gone. The lego dependency is dropped along
with its 181 transitively-imported DNS providers — net binary savings of
30–50 MB.
Task: letsencrypt
Section titled “Task: letsencrypt”Common parameters
Section titled “Common parameters”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
op | string | No | obtain | obtain / renew / revoke / info / list |
caURL | string | No | LE production | ACME directory URL; shortcuts: letsencrypt, staging, zerossl |
email | string | Yes (obtain/renew/revoke) | — | Account contact email |
storage | string | No | $XDG_DATA_HOME/letsencrypt | Filesystem path |
keyType | string | No | ECDSA-P256 | ECDSA-P256 / ECDSA-P384 / RSA-2048 / RSA-4096 / ED25519 |
timeout | duration | No | — | Wall-clock cap |
setvar | string | No | — | Capture result map into a workflow variable |
Challenge configuration (obtain / renew)
Section titled “Challenge configuration (obtain / renew)”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
challenge | string | No | dns-01 | Challenge type |
mustStaple | bool | No | false | OCSP must-staple |
DNS-01 fields: dnsProvider, dnsCredentials (same shape as the
dns task), dnsPropagation, dnsResolvers.
HTTP-01 fields: httpAddress (default :80).
TLS-ALPN-01 fields: tlsAddress (default :443).
Returns
Section titled “Returns”obtain / renew / info populate cert; list populates certs.
Both shapes carry: domains, notBefore, notAfter, issuer, serial,
fingerprint, daysRemaining, certPath, keyPath, fullchainPath.
revoke: { success, error }.
Examples
Section titled “Examples”Obtain a SAN cert via Cloudflare DNS-01
Section titled “Obtain a SAN cert via Cloudflare DNS-01”- name: cert letsencrypt: op: obtain storage: /var/lib/letsencrypt domains: - example.com - www.example.com - api.example.com challenge: dns-01 dnsProvider: cloudflare dnsCredentials: api_token: "{{ cf_token }}" setvar: certTest against Let’s Encrypt staging
Section titled “Test against Let’s Encrypt staging”- name: cert letsencrypt: op: obtain caURL: staging domains: ["dev.example.com"] challenge: dns-01 dnsProvider: cloudflare dnsCredentials: { api_token: "{{ cf_token }}" }HTTP-01 (host directly reachable on port 80)
Section titled “HTTP-01 (host directly reachable on port 80)”- name: cert letsencrypt: op: obtain domains: ["app.example.com"] challenge: http-01Force-renew
Section titled “Force-renew”- name: renew letsencrypt: op: renew domains: ["example.com", "www.example.com"] force: true challenge: dns-01 dnsProvider: cloudflare dnsCredentials: { api_token: "{{ cf_token }}" }Read existing cert without touching the CA
Section titled “Read existing cert without touching the CA”- name: info letsencrypt: op: info storage: /var/lib/letsencrypt domain: www.example.com setvar: cert
- name: report print: message: "expires in {{ cert.cert.daysRemaining }} days"Revoke a leaked-key cert
Section titled “Revoke a leaked-key cert”- name: revoke letsencrypt: op: revoke domain: oops.example.com reason: 1 # keyCompromise (RFC 5280) challenge: dns-01 dnsProvider: cloudflare dnsCredentials: { api_token: "{{ cf_token }}" }Namespace: letsencrypt
Section titled “Namespace: letsencrypt”Same five verbs under the letsencrypt script namespace.
let result = letsencrypt.obtain({ storage: "/var/lib/letsencrypt", domains: ["example.com", "www.example.com"], challenge: "dns-01", dnsProvider: "cloudflare", dnsCredentials: { api_token: cfToken }})log("cert at " + result.cert.certPath)See docs/namespaces/letsencrypt.md for
full reference.