Home > docs > getting started > Policies
Policies is a powerful and flexible mechanism to control different characteristics of processes and system entities.
A policy is a JSON document describing rules that can affect the execution of processes, creation of entities such as project and secrets, define the limits for the process queue, etc.
Policies can be applied system-wide as well as linked to an organization, a specific project or to a user.
Policies can be created using the Policy API. Currently, only the users with the administrator role can create or link policies.
Policies can inherent other policies - in this case the parent policies are applied first, going from the "oldest" ancestors to the latest link.
There are two types of objects in the policy document: allow/deny/warn
actions
and free-form group of attributes:
{
"[actionRules]": {
"deny": [
{
...rule...
}
],
"warn": [
{
...rule...
}
],
"allow": [
{
...rule...
}
]
},
"[anotherRule]": {
...rule...
}
}
Here’s the list of currently supported rules:
configuration
values;Attachment rules allow you to limit the size of process attachments.
The syntax:
{
"attachments": {
"msg": "The size of process attachments exceeds the allowed value: current {0} byte(s), limit {1} byte(s)",
"maxSizeInBytes": 1024
}
}
Concord applies the limit to all files stored in the process’
${workDir}/_attachments
directory, including the process state
files (variables, flow state, etc) and all files created during
the execution of the process.
Ansible rules allow you to control the execution of Ansible plays.
The syntax:
{
"action": "ansibleTaskName",
"params": [
{
"name": "paramName",
"values": ["arrayOfValues"]
}
],
"msg": "optional message"
}
The action
attribute defines the name of the Ansible step and the params
object is matched with the step’s input parameters. The error message can be
specified using the msg
attribute.
For example, to forbid a certain URI from being used in the Ansible’s get_url step:
{
"ansible": {
"deny": [
{
"action": "get_url",
"params": [
{
"name": "url",
"values": ["https://jsonplaceholder.typicode.com/todos"]
}
],
"msg": "Found a forbidden URL"
}
]
}
}
If someone tries to use the forbidden URL in their get_url
, they see a
message in the process log:
ANSIBLE: [ERROR]: Task 'get_url (get_url)' is forbidden by the task policy: Found a
ANSIBLE: forbidden URL
The Ansible rule supports regular JUEL expressions which are evaluated each time the Ansible plugin starts using the current process’ context. This allows users to create context-aware Ansible policies:
{
"ansible": {
"deny": [
{
"action": "maven_artifact",
"params": [
{
"artifact_url": "url",
"values": ["${mySecretTask.getForbiddenArtifacts()}"]
}
]
}
]
}
}
Note: the artifact_url
from the example above is not a standard
maven_artifact
step’s parameter. It is created dynamically from the supplied values of
repository_url
, group_id
, artifact_id
, etc.
Dependency rules provide a way to control which process dependencies are allowed for use.
The syntax:
{
"scheme": "...scheme...",
"groupId": "...groupId...",
"artifactId": "...artifactId...",
"fromVersion": "1.0.0",
"toVersion": "1.1.0",
"msg": "optional message"
}
The attributes:
scheme
- the dependency URL scheme. For example: http
or mvn
;groupId
and artifactId
- parts of the dependency’s Maven GAV (only for
mvn
dependencies);fromVersion
and toVersion
- define the version range (only for mvn
dependencies).For example, restricting a specific version range of a plugin can be done like so:
{
"dependency": {
"deny": [
{
"groupId": "com.walmartlabs.concord.plugins.basic",
"artifactId": "ansible-tasks",
"toVersion": "1.13.1",
"msg": "Usage of ansible-tasks <= 1.14.0 is forbidden"
}
]
}
}
In this example, all versions of the ansible-tasks
dependency lower than
1.13.1
are rejected.
Another example, warn users every time they are trying to use non-mvn
dependencies:
{
"dependency": {
"warn": [
{
"msg": "Using direct dependency URLs is not recommended. Consider using mvn:// dependencies.",
"scheme": "^(?!mvn.*$).*"
}
]
}
}
Dependency rewrite rules provide a way to change dependency artifacts (e.g. dependency versions).
The syntax:
{
"msg": "optional message",
"groupId": "...groupId...",
"artifactId": "...artifactId...",
"fromVersion":"...optional lower bound (inclusive) of version...",
"toVersion":"..optional upper bound (inclusive) of version...",
"value":"mvn://new dependency artifact"
}
The attributes:
groupId
and artifactId
- parts of the dependency’s Maven GAV;fromVersion
and toVersion
- define the version range;value
- new dependency value.For example, updating groovy dependency version to 2.5.21
:
{
"dependencyRewrite": [
{
"groupId": "org.codehaus.groovy",
"artifactId": "groovy-all",
"toVersion": "2.5.20",
"value": "mvn://org.codehaus.groovy:groovy-all:pom:2.5.21"
}
]
}
The dependency versions rule provides a way to map latest
version tags of
process dependencies to
actual version values.
The syntax:
[
{
"artifact": "...groupId:artifactId...",
"version": "...version"
},
{
"artifact": "...groupId:artifactId...",
"version": "...version"
},
...
]
The attributes:
artifact
- Maven’s groupId
and artifactId
values, separated by colon :
;version
- the artifact’s version to use instead of the latest
tag.For example:
{
"dependencyVersions": [
{
"artifact": "com.walmartlabs.concord.plugins.basic:ansible-tasks",
"version": "2.14.0"
},
{
"artifact": "mvn://com.walmartlabs.concord.plugins:jenkins-task",
"version": "2.5.0"
}
]
}
If a process specifies latest
instead of the version:
configuration:
dependencies:
- "mvn://com.walmartlabs.concord.plugins.basic:ansible-tasks:latest"
- "mvn://com.walmartlabs.concord.plugins:jenkins-task:latest"
the effective dependency list is:
- "mvn://com.walmartlabs.concord.plugins.basic:ansible-tasks:2.14.0"
- "mvn://com.walmartlabs.concord.plugins:jenkins-task:2.5.0"
Entity rules control the creation or update of Concord organizations, projects, secrets, etc.
The syntax:
{
"entity": "entityType",
"action": "action",
"conditions": {
"param": "value"
},
"msg": "optional message"
}
The currently supported entity
types are:
org
- organizations;project
- projects;repository
- repositories in projects;secret
- secrets;jsonStore
- JSON stores;jsonStoreItem
- items in JSON stores;jsonStoreQuery
- JSON store queries;trigger
- triggers.Available actions:
create
update
The conditions
are matched against an object containing both the entity’s
and the entity’s owner attributes:
{
"owner": {
"id": "...userId...",
"username": "...username...",
"userType": "LOCAL or LDAP",
"email": "...",
"displayName": "...",
"groups": ["AD/LDAP groups"],
"attributes": {
...other AD/LDAP attributes...
}
},
"entity": {
...entity specific attributes...
}
}
Different types of entities provide different sets of attributes:
org
:
id
- organization ID (UUID, optional);name
- organization name;meta
- metadata (JSON object, optional);cfg
- configuration (JSON object, optional).project
:
id
- project ID (UUID, optional);name
- project name;orgId
- the project’s organization ID (UUID);orgName
- the project’s organization name;visibility
- the project’s visibility (PUBLIC
or PRIVATE
);meta
- metadata (JSON object, optional);cfg
- configuration (JSON object, optional).repository
:
name
- repository name;url
- repository URL;branch
- branch name;secret
- reference to a secret (optional, JSON object, see below for
the list of fields);orgId
- the project’s organization ID (UUID);orgName
- the project’s organization name;projectId
- project ID (UUID);projectName
- project name.jsonStore
:
name
- JSON store name;orgId
- the store’s organization ID;visibility
- the store’s visibility (optional);ownerId
- user ID of the store’s owner (UUID, optional);ownerName
- username of the store’s owner (optional);ownerDomain
- user domain of the store’s owner (optional);ownerType
- user type of the store’s owner (optional).jsonStoreItem
:
path
- item’s path;data
- data (JSON object);jsonStoreId
- ID of the store (UUID);jsonStoreName
- name of the store;orgId
- the store’s organization ID (UUID);orgName
- the store’s organization name.jsonStoreQuery
:
name
- the query’s name;text
- the query’s text;storeId
- the store’s ID (UUID);storeName
- the store’s name;orgId
- the store’s organization ID (UUID);orgName
- the store’s organization name.secret
:
name
- project name;orgId
- the secrets’s organization ID (UUID);type
- the secret’s type;visibility
- the secret’s visibility (PUBLIC
or PRIVATE
, optional);storeType
- the secret’s store type (optional).trigger
eventSource
- the trigger’s event type (string, github
, manual
, etc);orgId
- linked organization’s ID (UUID, optional);params
- the trigger’s configuration (JSON object, optional).For example, to restrict creation of projects in the Default
organization use:
{
"entity": {
"deny": [
{
"msg": "project in default org are disabled",
"action": "create",
"entity": "project",
"conditions":{
"entity": {
"orgId": "0fac1b18-d179-11e7-b3e7-d7df4543ed4f"
}
}
}
]
}
}
To prevent users with a specific AD/LDAP group from creating any new entities:
{
"entity": {
"deny":[
{
"action": ".*",
"entity": ".*",
"conditions": {
"owner": {
"userType": "LDAP",
"groups": ["CN=SomeGroup,.*"]
}
}
}
]
}
}
Another example is a policy to prevent users from creating wide-sweeping, “blanket” GitHub triggers for all projects:
{
"entity": {
"deny": [
{
"msg": "Blanket Github triggers are disallowed",
"action": "create",
"entity": "trigger",
"conditions":{
"entity": {
"eventSource": "github",
"params": {
"org": "\\.\\*",
"project": "\\.\\*",
"repository": "\\.\\*",
"unknownRepo": [true, false]
}
}
}
}
]
}
}
The file rules control the types and sizes of files that are allowed in the process’ workspace.
The syntax:
{
"maxSize": "1G",
"type": "...type...",
"names": ["...filename patterns..."],
"msg": "optional message"
}
The attributes:
maxSize
- maximum size of a file (G
for gigabytes, M
- megabytes, etc);type
- file
or dir
;names
- filename patterns (regular expressions).For example, to forbid files larger than 128Mb:
{
"file": {
"deny": [
{
"maxSize": "128M",
"msg": "Files larger than 128M are forbidden"
}
]
}
}
The jsonStore
rule control parameters of JSON stores.
The syntax:
{
"data":{
"maxSizeInBytes": 100,
"msg": "optional message"
},
"store":{
"maxNumberPerOrg": 30,
"msg": "optional message"
}
}
The attributes:
data
maxSizeInBytes
- maximum allowed size of a store in bytes;store
maxNumberPerOrg
- maximum allowed number of stores per organization.Example:
{
"jsonStore":{
"data":{
"maxSizeInBytes": 1048576
},
"store":{
"maxNumberPerOrg": 30
}
}
}
The processCfg
values are merged into the process’ configuration
object,
overriding any existing values with the same keys:
{
"...variable...": "...value..."
}
Those values take precedence over the values specified by users in the process’
configuration
section. The defaultProcessCfg
rule can be used to set the initial values.
For example, to force a specific processTimeout value:
{
"processCfg": {
"processTimeout": "PT2H"
}
}
Or to override a value in arguments
:
{
"processCfg": {
"arguments": {
"message": "Hello from Concord!"
}
}
}
The defaultProcessCfg
rule allows settings initial values for process
configuration
.
{
"...variable...": "...value..."
}
Those values can be overriden by users their process’ configuration
sections.
The processCfg rule can be used to override any
user values.
For example, to set the default processTimeout value:
{
"defaultProcessCfg": {
"processTimeout": "PT2H"
}
}
The queue rule controls different aspects of the process queue - the maximum number of concurrently running processes, the default process timeout, etc.
The syntax:
{
"concurrent": {
"maxPerOrg": "10",
"maxPerProject": "5",
"msg": "optional message"
},
"forkDepth": {
"max": 5,
"msg": "optional message"
},
"processTimeout": {
"max": "PT1H",
"msg": "optional message"
}
}
The attributes:
concurrent
- controls the number of concurrently running processes:
maxPerOrg
- max number of running processes per organization;maxPerProject
- max number of running processes per project;forkDepth
- the maximum allowed depth of process forks, i.e. how many
ancestors a process can have. Can be used to prevent “fork bombs”;processTimeout
- limits the maximum allowed value of the
processTimeout parameter.For example:
{
"queue": {
"forkDepth": {
"max": 5
},
"concurrent": {
"max": 40
}
}
}
Task rules control the execution of flow tasks. They can trigger on specific methods or parameter values.
The syntax:
{
"taskName": "...task name...",
"method": "...method name...",
"params": [
{
"name": "...parameter name...",
"index": 0,
"values": [
false,
null
],
"protected": true
}
],
"msg": "optional message"
}
The attributes:
taskName
- name of the task (as in the task’s @Named
annotation);method
- the task’s method name;params
- list of the task’s parameters to match.The params
attribute accepts a list of parameter definitions:
name
- name of the parameter in the process’ Context
;index
- index of the parameter in the method’s signature;values
- a list of values to trigger on;protected
- if true
the parameter will be treated as a protected
variable.For example, if there is a need to disable a specific task based on some variable in the process’ context, it can be achieved with a policy:
{
"task": {
"deny": [
{
"taskName": "ansible",
"method": "execute",
"params": [
{
"name": "gatekeeperResult",
"index": 0,
"values": [
false,
null
],
"protected": true
}
],
"msg": "I won't run Ansible without running the Gatekeeper task first"
}
]
}
}
In this example, because the Ansible’s plugin method execute
accepts
a Context
, the policy executor looks for a gatekeeperResult
in
the process’ context.
The workspace rule allows control of the overall size of the process’ workspace.
The syntax:
{
"maxSizeInBytes": 1024,
"ignoredFiles": ["...filename patterns..."],
"msg": "optional message"
}
The attributes:
maxSizeInBytes
- maximum allowed size of the workspace minus the
ignoredFiles
(in bytes);ignoredFiles
- list of filename patterns (regular expressions). The
matching files will be excluded from the total size calculation.Example:
{
"workspace": {
"msg": "Workspace too big (allowed size is 256Mb, excluding '.git')",
"ignoredFiles": [
".*/\\.git/.*"
],
"maxSizeInBytes": 268435456
}
}
The runtime rule controls allowed runtime(s) for process execution.
The syntax:
{
"msg": "optional message",
"runtimes": ["concord runtime(s)..."]
}
The attributes:
runtimes
- List of allowed concord runtime(s);Example:
{
"runtime": {
"msg": "{0} runtime version is not allowed",
"runtimes": ["concord-v2"]
}
}
RawPayload rules allows you to limit the size of the raw payload archive sent to start the process.
The syntax:
{
"rawPayload": {
"msg": "Raw payload size too big: current {0} bytes, limit {1} bytes",
"maxSizeInBytes": 1024
}
}
Cron trigger rule allows you, administrators to set the minimum interval between the process triggered by cron.
The syntax:
{
"cronTrigger": {
"minInterval": "interval in seconds"
}
}
For example:
{
"cronTrigger": {
"minInterval": 61
}
}