Polycrate API for Teams: Centralized Monitoring and Remote Triggering
TL;DR The Polycrate API transforms individual workspaces into a team platform: all workspaces, …
Diese Serie zeigt Schritt für Schritt, wie Ansible mit Polycrate zu einer strukturierten, teilbaren und compliance-fähigen Automatisierungsplattform wird – von den Grundlagen bis zu Enterprise-Szenarien.
check) and correcting (remediate), generates audit reports as JSON/CSV, and stores them structured in the workspace – including Git history as an audit trail.Many compliance teams still work with Excel checklists or Word documents:
This works as long as you have few systems and infrequent audits. At the latest with:
the model becomes fragile:
Policy as Code turns this around: The checklist becomes executable code. The question is no longer “Who checked what and how?”, but:
This is where Polycrate with Ansible comes in – without you needing to be a developer.
Policy as Code means: Compliance requirements are described in a machine-readable form. For our purposes:
Example: A CIS benchmark requires that /etc/passwd is readable but not writable for “Others”. Instead of ticking “OK” in Excel, you define a task:
The advantage:
With Polycrate, you link these playbooks to a structured environment (workspace), container-based tooling, and Git – making Policy as Code manageable for compliance officers.
What distinguishes Polycrate from “plain” Ansible from a compliance perspective?
With classic Ansible, you often have to:
The “dependency problem” leads to:
With Polycrate:
You start a compliance check with one command, without worrying about the local technology. Details on Ansible integration can be found in the documentation on Ansible and Polycrate.
Polycrate forces your automation into a clear structure:
acme-corp-automation)cis-linux-baseline)check, remediate)This prevents loose playbooks from lying around everywhere that no one can assign anymore. More on this in the Best Practices.
Compliance checks often work with:
The Polycrate workspace can be encrypted with age – without an additional tool like Vault. This keeps sensitive information protected in the repository. The details are in the documentation on Workspace Encryption.
A central component for audits: every change, every check, every report is traceable in Git. Polycrate works ideally with Git, for example:
artifacts/ directory,Polycrate’s Git integration is described in the documentation on Git Workflows.
In the following, we build a simple block that does two things:
check: Perform CIS-like checks on Linux servers.remediate: Automatically correct some deviations.Target audience: Linux servers (e.g., Ubuntu 22.04) in a domain acme-corp.com.
In the workspace root, you create the workspace.poly:
name: acme-corp-automation
organization: acme
blocks:
- name: cis-linux-baseline
from: registry.acme-corp.com/acme/compliance/cis-linux-baseline:0.1.0
config:
report_format: "json"The block is pulled via from: from an OCI registry (here fictional registry.acme-corp.com/...; public examples include cargo.ayedo.cloud or PolyHub). The version is pinned in from: (:0.1.0). Output paths for reports do not belong in workspace.poly / block.poly; derive them in the playbook from block.artifacts.path – see Artifacts.
The YAML inventory is also located in the workspace root as inventory.yml:
all:
hosts:
server01.acme-corp.com:
ansible_user: ubuntu
server02.acme-corp.com:
ansible_user: ubuntuPolycrate automatically sets ANSIBLE_INVENTORY to this file. The playbooks can simply use hosts: all – they run in the container but access your servers via SSH.
After polycrate blocks pull, the block lives under blocks/registry.acme-corp.com/acme/compliance/cis-linux-baseline/. There you create the block.poly (name = full registry path without tag):
name: registry.acme-corp.com/acme/compliance/cis-linux-baseline
version: 0.1.0
kind: generic
config:
report_format: "json"
actions:
- name: check
playbook: check.yml
- name: remediate
playbook: remediate.ymlKey points:
version pins the block state – important for traceability in audits.report_format per instance in workspace.poly – literal YAML values only, no Jinja2 expressions. There is no template substitution in workspace.poly and block.poly (no Jinja2); set dynamic paths in Ansible, e.g. via block.artifacts.path. Details: Configuration – limitations and Blocks.Now the check.yml in the same directory:
- name: CIS Linux Baseline Check
hosts: all
become: true
gather_facts: false
vars:
cis_results: []
report_dir: "{{ block.artifacts.path }}/reports"
tasks:
- name: Check 1 – /etc/passwd permissions
ansible.builtin.stat:
path: /etc/passwd
register: passwd_stat
- name: Evaluate 1 – /etc/passwd should be 0644
ansible.builtin.assert:
that:
- passwd_stat.stat.mode == "0644"
fail_msg: "/etc/passwd permissions are not 0644"
success_msg: "/etc/passwd permissions are 0644"
register: passwd_check
- name: Check 2 – SSH root login disabled
ansible.builtin.command: "sshd -T"
register: sshd_config
changed_when: false
- name: Evaluate 2 – PermitRootLogin should be no
ansible.builtin.assert:
that:
- "'permitrootlogin no' in sshd_config.stdout_lines"
fail_msg: "SSH root login is not disabled"
success_msg: "SSH root login is disabled"
register: ssh_root_check
- name: Build CIS result structure
ansible.builtin.set_fact:
cis_results: >-
{{
cis_results + [
{
"control": "CIS-5.4.1",
"description": "/etc/passwd permissions 0644",
"passed": passwd_check is succeeded
},
{
"control": "CIS-5.2.8",
"description": "SSH root login disabled",
"passed": ssh_root_check is succeeded
}
]
}}
- name: Ensure report directory exists
ansible.builtin.file:
path: "{{ report_dir }}"
state: directory
mode: "0750"
- name: Write JSON report
ansible.builtin.copy:
dest: "{{ report_dir }}/cis-linux-{{ inventory_hostname }}.json"
content: "{{ cis_results | to_nice_json }}"
mode: "0640"What happens here:
ansible.builtin.stat checks file permissions.ansible.builtin.command reads the current SSHD configuration.ansible.builtin.assert evaluates whether the target state is met.ansible.builtin.file creates the report directory under {{ block.artifacts.path }}/reports (not as a fixed path in block.poly – see Artifacts).ansible.builtin.copy writes a JSON report per host into that directory.The modules are deliberately kept simple – compliance officers can easily understand the text in description and fail_msg.
Now the remediate.yml:
- name: CIS Linux Baseline Remediation
hosts: all
become: true
gather_facts: false
tasks:
- name: Fix 1 – Set /etc/passwd permissions to 0644
ansible.builtin.file:
path: /etc/passwd
mode: "0644"
- name: Fix 2 – Disable SSH root login in sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
create: no
backup: yes
- name: Reload SSH service
ansible.builtin.command: "systemctl reload sshd"
changed_when: trueThis playbook uses:
ansible.builtin.file to set file permissions.ansible.builtin.lineinfile (in addition to the required module set) to adjust the SSH configuration.ansible.builtin.command to reload the service.Important: Idempotency. If a system is already compliant, files do not change unnecessarily – a core principle of Ansible.
From the workspace root, you can start the actions directly:
polycrate run cis-linux-baseline checkAfter completion, you will find a JSON report for each host under {{ block.artifacts.path }}/reports/ (typically artifacts/blocks/<registry-path>/reports/).
If you want to correct deviations:
polycrate run cis-linux-baseline remediateAnd then check again:
polycrate run cis-linux-baseline checkWith “plain” Ansible, you would have to:
With Polycrate, this is reduced to clear, non-technical commands – well-suited to give, for example, an ISO its own “compliance console.”
Typical procedure for a documented check:
# Decrypt workspace if necessary
polycrate workspace decrypt
# Execute compliance check
polycrate run cis-linux-baseline check
# View results (path = block artifacts + /reports)
ls artifacts/blocks/registry.acme-corp.com/acme/compliance/cis-linux-baseline/reports/
cat artifacts/blocks/registry.acme-corp.com/acme/compliance/cis-linux-baseline/reports/cis-linux-server01.acme-corp.com.json
# Commit changes to the Git repository
git add artifacts/blocks/
git commit -m "CIS Linux baseline check 2026-03-25"
git pushIn an audit you can then show:
version) was used,NIS-2 (Directive (EU) 2022/2555) entered into force on 16.01.2023; member states had to transpose measures by 17.10.2024, with application from 18.10.2024. GDPR has been in effect since 25.05.2018.
Both regimes require, in simplified terms:
With Policy as Code you can automatically check, for example:
These technical controls support:
Polycrate helps because:
For more complex environments (e.g. mixed Linux/Windows or OT/IoT), you can build more blocks or pull them from PolyHub or your own registries and share them in a versioned way (“sharable automation”).
No. You should be able to:
Polycrate encapsulates the actual technology (container, Ansible, Python). Many compliance teams work like this: a technically savvy colleague or external partner builds the blocks; the compliance team runs them with simple commands and interprets the reports.
Policy as Code complements your existing policies:
Git history and Polycrate workspaces yield consistent evidence that integrates well with GRC tools or audit documentation.
Experience shows: once the first two or three blocks exist, the barrier drops sharply. Clear roles matter:
Polycrate supports this split through clear actions and a simple CLI. In addition, the Polycrate API provides higher-level interfaces: workspaces, blocks, and actions can be invoked from other tools or self-service front ends – useful when not all stakeholders use the command line.
More questions? See our FAQ.
With the example above you have seen:
check and remediate actions,block.artifacts.path and become a solid audit trail with Git,For many organizations the decisive step is not a single playbook but building a repeatable platform for compliance automation:
This is where ayedo fits in: we combine open-source tools like Polycrate with proven platform engineering approaches and help you introduce Policy as Code so it stays understandable for compliance teams, operable for IT, and defensible for auditors.
If you want to take the next step and shape a solution for your environment, we are happy to start with a hands-on format – overview and booking:
TL;DR The Polycrate API transforms individual workspaces into a team platform: all workspaces, …
TL;DR Polycrate not only logs Action Runs (Ansible playbooks) but also SSH sessions, workspace …
TL;DR A well-named, clearly structured Polycrate workspace is half the battle: a consistent name …