Cloud

Secure Portainer with cnspec

Scan Portainer container-management instances against security and compliance best practices with cnspec.

Scan your Portainer instance to find control-plane security risks before they become incidents. cnspec audits the instance authentication settings, the container-security flags that govern what regular users can do, user and team RBAC, and the environments (Docker hosts, Docker Swarm or Kubernetes clusters, and Edge agents) that Portainer manages, all without installing agents on your infrastructure.

New to cnspec? Read the Quickstart to install cnspec and run your first scan. To scan other platforms, see the cloud scanning overview.

Prerequisites

To scan Portainer with cnspec, you must have:

  • cnspec installed on your workstation
  • A Portainer instance (Community or Business Edition, 2.x)
  • A Portainer access token. Use a token from an administrator account to audit the full instance, because a token inherits the permissions of the user who created it.
  • Network access from your workstation to the Portainer instance

Authenticate

Create an access token in Portainer:

  1. Log in to the Portainer web UI as an administrator.
  2. Open the user menu in the top-right corner and choose My account.
  3. In the Access tokens section, select Add access token.
  4. Give the token a description, then create it.
  5. Copy the resulting token value. Portainer shows it only once and it has the form ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx=.

cnspec reads the instance address and access token from command-line flags or from the PORTAINER_ADDRESS and PORTAINER_ACCESS_TOKEN environment variables.

Verify with a quick Portainer check

Confirm that cnspec can reach your Portainer instance. The address is a positional argument; it can be a bare host, host:port, or a full URL (cnspec assumes https when you omit the scheme):

cnspec run portainer https://portainer.example.com \
  --access-token ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx= \
  -c 'portainer.version != empty'

If your Portainer instance uses a self-signed certificate, add --insecure (or -k) to skip TLS verification.

Scan Portainer

Scan your Portainer instance:

cnspec scan portainer https://portainer.example.com \
  --access-token ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx=

When the scan completes, cnspec prints each check with a pass or fail result and an overall risk score from 0 (no risk) to 100 (highest risk). To learn how to read a report in depth, see Understand Scan Results.

By default cnspec scans the Portainer instance itself. To also scan the environments Portainer manages, use discovery:

cnspec scan portainer https://portainer.example.com \
  --access-token ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx= \
  --discover environments,docker,kubernetes,edge

Scan with a policy

Mondoo does not yet ship an out-of-the-box Portainer policy. You can write your own policies to encode the control-plane checks that matter to your organization, such as enforcing a minimum password length, requiring that regular users cannot run privileged containers, and limiting the number of administrator accounts.

To run a policy bundle you authored, pass it to cnspec with --policy-bundle:

cnspec scan portainer https://portainer.example.com \
  --access-token ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx= \
  --policy-bundle ./my-portainer-policy.mql.yaml

Explore and test checks interactively

Open a cnspec shell to discover resources and try out checks:

cnspec shell portainer https://portainer.example.com \
  --access-token ptr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx=

Instance overview

cnspec> portainer { version instanceId }

Review instance security settings

cnspec> portainer.settings {
  authenticationMethod
  requiredPasswordLength
  allowPrivilegedModeForRegularUsers
  allowBindMountsForRegularUsers
  allowHostNamespaceForRegularUsers
  allowDeviceMappingForRegularUsers
}

Find regular-user permissions that allow privilege escalation

cnspec> portainer.settings.allowPrivilegedModeForRegularUsers == false

List administrator accounts

cnspec> portainer.users.where(role == "administrator") { id username }

Audit teams and their membership

cnspec> portainer.teams { name members { username } }

List the environments Portainer manages

cnspec> portainer.environments { id name type status containerEngine tlsEnabled }

Find environments reachable without TLS

cnspec> portainer.environments.where(tlsEnabled == false) { name url type }

Inspect Edge stacks

cnspec> portainer.edgeStacks { name deploymentType numDeployments }

Review applied licenses

cnspec> portainer.licenses { company nodes expiresAt }

Learn more

On this page