TL;DR
- Unencrypted SSH keys, plaintext passwords, and credentials in wikis pose a compliance risk—especially under GDPR (since 25.05.2018) and NIS-2 (effective 17.10.2024).
- Polycrate includes workspace encryption: All secrets are stored as files in the workspace, encrypted with
age, and can be securely versioned in the Git repository. secrets.polyholds sensitive block configuration (overrides toworkspace.poly); together with files underartifacts/secrets/, everything is encrypted with a single workspace encryption key (primarily via the Polycrate API orWORKSPACE_ENCRYPTION_KEY) usingage; at runtime Polycrate exposes decrypted paths—access in playbooks viaworkspace.secrets[...].- The workflow is simple:
polycrate workspace decryptto work, secure changes before committing withpolycrate workspace encrypt—no external tools, no additional secret management system. - ayedo combines workspace encryption with Platform Engineering: Polycrate offers a containerized toolchain, guardrails through the block model, and an API-enabled ecosystem that considers security and compliance requirements from the start.
The Secrets Problem: When Convenience Becomes Liability
Anyone who has worked extensively with Ansible, shell scripts, or manual administration is familiar with typical patterns:
- SSH private keys are stored in the project folder so that "it works for everyone."
- Database passwords are in
group_vars/all.ymlin plaintext. - VPN credentials are "quickly" shared via email or chat.
- For an audit, proving where credentials were stored is laborious—often without a clear answer.
Under GDPR and NIS-2, this is not just unsightly but a real risk:
- If a Git repository with plaintext secrets is lost (e.g., through a compromised developer laptop), you may need to report a security incident.
- Without technical and organizational measures (TOMs) to protect access data, accountability is violated.
With plain Ansible, there is Ansible Vault, but:
- it only encrypts Ansible content, not your entire automation toolchain,
- you need additional processes for other tools (kubectl, OpenSSL, custom scripts),
- collaboration with multiple team members is often cumbersome.
Polycrate addresses this directly: Workspace encryption is a core feature—not an afterthought.
Polycrate Workspace Encryption: age Instead of Password Cryptography
Polycrate uses age as the encryption format. This means:
- Modern cryptography with clear primitives.
- One workspace encryption key per workspace: resolution in practice follows Polycrate API →
WORKSPACE_ENCRYPTION_KEY→ interactive prompt (see architecture in the documentation). - File-based:
secrets.polyand files underartifacts/secrets/**become.ageartifacts; only encrypted variants belong in Git.
The details are described in the Polycrate documentation:
Workspace Encryption in Polycrate
The basic idea:
- You place secret files in
artifacts/secrets/(e.g.,id_rsa, DB password file, kubeconfig) and optionally sensitive entries insecrets.poly(block overrides). - You encrypt with
polycrate workspace encrypt—Polycrate obtains the key from the API or environment (see above). - The repository contains
secrets.poly.ageandartifacts/secrets/**/*.age. - When an action runs, Polycrate decrypts transparently in the container—playbooks access paths via
workspace.secrets[...].
No additional binary like sops, no external storage like HashiCorp Vault, no "only for Ansible" like Ansible Vault. Everything stays within the Polycrate workspace.
secrets.poly: Structure, Merge with workspace.poly, and the Path into the Playbook
secrets.poly sits in the workspace root (next to workspace.poly). As in the official documentation, it contains no recipients list—only sensitive block configuration that overrides values from workspace.poly. Merge priority: block.poly < workspace.poly < secrets.poly. See Workspace encryption – secrets.poly.
A fictional example:
# secrets.poly – sensitive overrides (encrypted together)
blocks:
- name: linux-user-ssh
config:
deploy_key_comment: "acme-deploy@2026"
Encryption uses one workspace encryption key (not a per-person recipient list in secrets.poly). Key sources and flow: Workspace encryption – overview and architecture.
Polycrate encrypts secrets.poly and relevant files under artifacts/secrets/. In playbooks you reference decrypted files via workspace.secrets['<filename>'] (path inside the action container).
Example block.poly after pulling from a registry (name = full registry path without tag):
# blocks/registry.acme-corp.com/acme/ops/linux-user-ssh/block.poly
name: registry.acme-corp.com/acme/ops/linux-user-ssh
version: 0.1.0
kind: generic
config:
username: "deploy"
ssh_private_key_file: "id_deploy" # filename in artifacts/secrets/
actions:
- name: provision
playbook: provision.yml
In the Ansible playbook, you reference the secret via workspace.secrets[...]:
# blocks/registry.acme-corp.com/acme/ops/linux-user-ssh/provision.yml
- name: Create Linux user for deployments
hosts: all
become: true
vars:
deploy_user: "{{ block.config.username }}"
tasks:
- name: Create user
ansible.builtin.user:
name: "{{ deploy_user }}"
shell: /bin/bash
state: present
- name: Create .ssh directory
ansible.builtin.file:
path: "/home/{{ deploy_user }}/.ssh"
state: directory
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0700"
- name: Deploy private key (from workspace secret)
ansible.builtin.copy:
src: "{{ workspace.secrets[block.config.ssh_private_key_file] }}"
dest: "/home/{{ deploy_user }}/.ssh/id_rsa"
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0600"
What happens here:
workspace.secrets["id_deploy"]is a path in the Polycrate container where the decrypted file is provided.- Your playbook remains idempotent and clearly readable—no cryptographic overhead in the task itself.
With plain Ansible, you would now have to work with Ansible Vault, manage the file outside of the playbooks, or build your own scripts around it. With Polycrate, the reference via workspace.secrets is sufficient.
Complete Workspace Example: Securely Versioning SSH Key in Git
Consider a simple workspace acme-corp-automation that manages ACME's Linux servers:
# workspace.poly
name: acme-corp-automation
organization: acme
blocks:
- name: linux-user-ssh
from: registry.acme-corp.com/acme/ops/linux-user-ssh:0.1.0
config:
username: "deploy"
ssh_private_key_file: "id_deploy"
The inventory lives in the workspace root as inventory.yml. No Jinja in the inventory file: {{ workspace.secrets[...] }} is not evaluated there. For Ansible’s SSH connection, Polycrate typically uses the private key at artifacts/secrets/id_rsa when present (see Workspace encryption):
# inventory.yml
all:
hosts:
server01.acme-corp.com:
ansible_user: ubuntu
We use two secret files:
artifacts/secrets/id_rsa—SSH key for Ansible to reach the hosts (usual default)artifacts/secrets/id_deploy—key for the new deploy user (referenced viaworkspace.secretsin the playbook)
Unencrypted copies exist only locally:
artifacts/secrets/id_rsa
artifacts/secrets/id_deploy
Only encrypted .age artifacts belong in Git.
Encrypting and Executing the Workspace
Ensure the workspace encryption key is available (Polycrate API, WORKSPACE_ENCRYPTION_KEY, or prompt—see architecture). Then:
# Set up the workspace once
polycrate workspace decrypt # if already cloned encrypted
polycrate workspace encrypt # encrypts all files in artifacts/secrets/
To execute the block:
# Always in the container from Polycrate's perspective
polycrate run linux-user-ssh provision
Polycrate ensures that:
- when the action starts, the secrets are decrypted and provided in the container,
ANSIBLE_INVENTORYis automatically set toinventory.yml,- the entire toolchain (Ansible, Python, SSH binary, possibly kubectl/Helm) runs in the container—no local dependencies, no Python chaos.
This addresses not only the secrets problem but also the classic dependency problem of automation stacks: All tools are defined in the container (Dockerfile.poly / Bash script), consistent everywhere, and do not need to be manually updated on every laptop.
The Daily Workflow: encrypt, decrypt, commit
Workspace encryption is only helpful if it doesn't slow down daily operations. A typical daily routine:
- Clone the workspace
git clone git@git.acme-corp.com:platform/acme-corp-automation.git
cd acme-corp-automation
- Decrypt secrets locally
If you have the workspace encryption key (e.g., via API, WORKSPACE_ENCRYPTION_KEY, or a team process):
polycrate workspace decrypt
Polycrate detects encrypted files under artifacts/secrets/ and secrets.poly.age and creates unencrypted versions—only on your local filesystem.
- Make changes
-
Create a new secret file, e.g., a new DB password:
echo "super-secure-db-password" > artifacts/secrets/db_password -
Adjust the block to use the secret.
- Extend the playbook.
- Local testing
polycrate run linux-user-ssh provision
- Encrypt again before committing
polycrate workspace encrypt
git status
git add .
git commit -m "Added new deploy user + DB secret"
In Git you commit encrypted artifacts (*.age, secrets.poly.age). Without the workspace encryption key they are useless—a strong argument in any GDPR or NIS-2 risk analysis.
One Workspace Encryption Key and Team Collaboration
Encryption uses one workspace encryption key per workspace (no recipient list in secrets.poly). Best practice: let the Polycrate API manage keys and credentials so developers do not pass keys around by hand. Second-best without the API: generate a key with polycrate tools pwgen -a age, store the AGE-SECRET-KEY-... line safely (e.g., Keeper, Bitwarden, Vaultwarden), and set it as WORKSPACE_ENCRYPTION_KEY when running polycrate workspace encrypt / decrypt (see documentation).
Organizationally, you still need clarity on who receives API access or the key, who reviews secret changes, and how rotation and offboarding work—this complements technical encryption; it does not replace it.
GDPR and NIS-2 Compliance: Encrypted in the Git Repo—and Good?
Of course, workspace encryption does not replace a full data protection impact assessment, but it is a strong technical pillar:
- Confidentiality: Secrets are only stored encrypted in Git. A data leak of the repository does not automatically mean a secret leak.
- Integrity: Changes to
secrets.poly, secret files, and.ageartifacts are versioned. You can see when configuration or secrets changed. - Availability: No dependency on a central Vault cluster—as long as the workspace encryption key (or API-backed access) is organized for the team, secrets stay usable and automation can run.
Since 25.05.2018, GDPR expects demonstrable technical and organizational measures to protect personal data. For NIS-2–relevant operators (from 17.10.2024), similar expectations apply for critical infrastructures.
Polycrate helps you meet these requirements in infrastructure automation without introducing a separate secret-management product. Combined with a disciplined Platform Engineering approach, you get a consistent, audit-friendly baseline.
Comparison with Vault, SOPS, and Ansible Vault
HashiCorp Vault
Vault is powerful—but:
- requires a cluster, storage backend, HA setup, and backup strategy,
- needs operational processes and monitoring,
- adds noticeable complexity and cost.
For many teams that is overkill, especially when "only" automation workspace secrets are involved.
Polycrate aims lower:
- No extra infrastructure.
- Encryption where you work—in the workspace.
- Enough for many GDPR / NIS-2 automation scenarios.
SOPS
SOPS is excellent for encrypted YAML/JSON, but:
- it is another binary to install and update on every workstation,
- you need processes for how SOPS integrates with Ansible, Terraform, kubectl, etc.,
- it does not solve your toolchain dependency problem.
With Polycrate you get workspace encryption, a containerized toolchain (Ansible, kubectl, Helm, Python …), and the block model as a guardrail—one story, no workflow break.
Ansible Vault
Ansible Vault is tightly integrated with Ansible—and therefore limited:
- You can only encrypt content Ansible understands (vars, files).
- Other repo content (shell scripts, TLS certs, kubeconfigs) falls outside.
- Team sharing is often awkward; vault passwords must be managed separately.
Polycrate goes further:
- Encrypts everything under
artifacts/secrets/regardless of tool. - Exposes files to actions in the container via
workspace.secrets[...]—Ansible, kubectl, bash, or custom binaries. - Sharable automation: blocks can be versioned and shared via an OCI registry, e.g. PolyHub. Workspace secrets stay with the team, not the block author.
Frequently Asked Questions
Do all team members have to share the same age private key?
Workspace encryption uses one shared workspace encryption key (not per-user recipients in secrets.poly). Recommended: do not distribute the key via chat; use the Polycrate API or a password manager / confidential handover—as in the official docs. Revoking access is organizational (API permissions, key rotation, removal from the password manager) and via your Git/review processes—not by "removing recipients from secrets.poly."
What happens if someone clones the workspace without the workspace encryption key?
Encrypted files under artifacts/secrets/ and secrets.poly.age are visible in the repo but useless without the workspace encryption key. polycrate workspace decrypt then fails or prompts for the key. That is intended: code is readable, secrets are not—good for separated roles (e.g., developers without production access).
How does workspace encryption fit a larger compliance framework?
It is one technical control among many—for GDPR TOMs or NIS-2 measure catalogs. Together with role definitions, logging of automation runs, and clear key-management processes, you can show auditors that access to secrets is governed, secrets live encrypted in SCM, and changes are traceable.
More questions? See our FAQ.
Compliance in Practice
Workspace encryption with Polycrate is not a theoretical security feature you forget in daily work. It is embedded in the workflow:
- You work in a structured workspace with blocks instead of playbook sprawl.
- Your toolchain runs in a container—reproducible and independent of local installs.
- Secrets are provided where needed without juggling plaintext files.
ayedo helps organizations at the intersection of automation, security, and compliance—whether extending existing Ansible estates or adopting modern Platform Engineering. We help you migrate playbooks into Polycrate blocks, wire workspace encryption into Git and review flows, and make GDPR and NIS-2 requirements concrete in infrastructure automation.
If you want to see how this feels in practice—including polycrate workspace encrypt/decrypt, secrets.poly, and workspace.secrets in your own playbooks—take a look at our Workshops.