A protected environment restricts deployments to an environment. Only those who are explicitly allowed can run a deployment job, and a deployment can additionally require approvals before the job runs. Protection is typically used for environments that serve users, such as production.

Protection is configured in a project for an environment name, and in a group for a deployment tier. A group rule applies to every project of the group and its subgroups.

How protected environments work

The “Allowed to deploy” list of a rule names who can run a deployment job for the environment, and who can change, stop, or delete the environment itself. The “Approval rules” list names whose approval a deployment needs, and how many approvals each subject must give.

The rule owner determines what the rule name means:

Rule ownerRule name
ProjectExact name of the project environment. The name is case-sensitive, so a rule named Production does not protect the production environment
GroupOne deployment tier: production, staging, testing, development, or other. The rule applies to every environment of that tier in the projects of the group and its subgroups

The tier of an environment comes from the deployment_tier keyword in the CI/CD configuration file. If the keyword is omitted, Deckhouse Code derives the tier from the environment name, looking for the following substrings regardless of their case:

TierSubstrings in the environment name
developmentdev, review, trunk
testingtest, tst, int, acpt, accept, qa, qc, control, quality
stagingstg, stag, modl, model, pre, demo, non
productionprod, prd, live

The rows are checked in this order, and the first match determines the tier. The dev-live environment gets the development tier. A name that contains none of these substrings gets the other tier.

A deployment to an environment is governed by the project rule for its name together with the group rules for its tier, and all these rules apply at the same time. To run the deployment job, a user must be listed in “Allowed to deploy” of every applicable rule. To deploy, the approvals required by the approval rules of every applicable rule must be collected.

Instance administrators can deploy under any rule and approve through any approval rule. These privileges, and every other administrator exemption named on this page, work independently of admin mode.

An administrator who is not a member of the project gets access to the project and its jobs after switching into admin mode, when it is enabled on the instance. A deployment created by their own job is the exception. It follows “Approving your own deployment” like any other.

Prerequisites

Before configuring protected environments, make sure the following requirements are met:

  • CI/CD is enabled in the project.
  • The CI/CD configuration file contains a job with the environment keyword.
  • The user has the Maintainer or Owner role to configure project rules, or the Owner role in the group to configure group rules.

A project rule can be configured before the environment is created. Once the environment is created, it is protected immediately if its name matches the rule name.

Protecting an environment in a project

You can protect a project environment through the web interface or API.

  • Protecting via web interface
  • Protecting via API

To protect an environment:

  1. Open the project.
  2. Go to “Settings” → “CI/CD”.
  3. Expand the “Protected environments” section.
  4. Click “Add protected environment”.
  5. In “Environment name”, specify the exact name of the environment.
  6. In “Allowed to deploy”, select roles, users, or groups. For details, refer to Deployment permissions.
  7. In “Approval rules”, select the subjects whose approval a deployment needs, and set “Required approvals” for each role and group. For details, refer to “Approval rules”.
  8. Click “Create protected environment”.

One subject holds one entry in each list. A role, user, or group already present in “Allowed to deploy” is not added to that list a second time, and the same holds for “Approval rules”. The same subject can be present in both lists at once.

The rule appears in the “Configured protected environments” table. Rules inherited from the group hierarchy are listed separately in the “Inherited protected environments” table.

To change a rule, click “Edit” in its row. The environment name is set when the rule is created and cannot be changed afterwards. To protect a different name, create a new rule.

To stop protecting an environment, click “Delete” in its row and confirm the deletion in the “Delete protected environment?” dialog. Deletion also removes the deploy access entries and approval rules of the rule.

To protect an environment via API, run the following request:

curl --request POST --header "PRIVATE-TOKEN: <TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "production",
    "deploy_access_levels": [{ "access_level": 40 }],
    "approval_rules": [{ "access_level": 40, "required_approvals": 2 }]
  }' \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/protected_environments"

Where:

  • <TOKEN>: Token used to authenticate with Deckhouse Code
  • <HOST>: Deckhouse Code instance address
  • <PROJECT_ID>: Project ID

The following parameters can be specified in the request:

ParameterRequired for creationDescription
nameYesExact name of the environment to protect. It is matched case-sensitively and cannot be changed afterwards
deploy_access_levelsYesEntries of the “Allowed to deploy” list. Each entry names its subject by access_level, user_id, or group_id, and a group entry also accepts group_inheritance_type
approval_rulesNoApproval rules. Each entry names its subject the same way and adds required_approvals
required_approval_countNoDeprecated parameter kept for compatibility. It accepts only 0; the number of approvals is set per rule in approval_rules

The access_level parameter accepts the following values:

  • 20: Reporter
  • 30: Developer
  • 40: Maintainer
  • 60: Instance admins

The access_level_description field in a response contains:

  • For 30: Developers + Maintainers
  • For 40: Maintainers
  • For 20 and 60: An empty value
  • For an entry with a user or group: The user name or group name

An entry passed with an id is updated, while an entry passed without an id is created. To remove an entry, pass its id together with "_destroy": true. To keep the current subject of an entry and change only its group_inheritance_type or required_approvals, pass the id without access_level, user_id, and group_id.

If a request names a subject that cannot be applied to the rule, the entire request is rejected. A partially applied configuration is not saved.

Reading configuration:

# All project rules, sorted by name.
curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/protected_environments"

# Rules inherited from the project group hierarchy, with their owner group.
curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/protected_environments/inherited"

# One rule.
curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/protected_environments/<ENVIRONMENT_NAME>"

Changing configuration:

# Changing the lists of an existing rule.
curl --request PUT --header "PRIVATE-TOKEN: <TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{ "approval_rules": [{ "access_level": 40, "required_approvals": 1 }] }' \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/protected_environments/<ENVIRONMENT_NAME>"

# Removing protection.
curl --request DELETE --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/protected_environments/<ENVIRONMENT_NAME>"

Both endpoints that return rule lists support pagination. Use page to select the page and per_page to set the number of entries per page.

If an environment name contains a slash, encode it as %2F in the request path. For example, use review%2Feu for the review/eu environment. An unencoded slash is treated as a path segment separator, so a request with review/eu does not match the route and returns 404.

Possible response codes:

CodeDescription
200Configuration returned or updated
201Protected environment created
204Protection removed
400Request rejected
401Request was made without authentication
403User role does not allow the operation
404Project or protected environment not found (the environment name is matched case-sensitively)
409Protected environment with this name already exists in the project, another request is changing the same rule, or a parallel request has just added the same subject
422The subject of an entry already has an entry in the same list, or required_approval_count was passed with a positive value

A 400 response is returned if:

  • The subject cannot be applied to the rule
  • required_approvals is outside the allowed range
  • required_approval_count is negative
  • A nested entry with the specified id does not belong to the rule

Protecting environments in a group

A group rule protects environments by deployment tier, so one rule covers the environments of that tier in every project of the group and its subgroups.

To create a group rule:

  1. Open the group.
  2. Go to “Settings” → “CI/CD”.
  3. Expand the “Protected environments” section.
  4. Click “Add protected environment”.
  5. In “Environment name”, select the deployment tier:
    • “Production”
    • “Staging”
    • “Testing”
    • “Development”
    • “Other”
  6. In “Allowed to deploy” and “Approval rules”, select the subjects.
  7. Click “Create protected environment”.

Subjects of a group rule are limited to the group hierarchy:

SubjectRequirements
RoleThe form offers only “Maintainer”. Through the API, a group rule accepts the same access_level values as a project rule
UserHas the Maintainer or Owner role in the group, including a role inherited from a parent group
GroupThe group itself, one of its subgroups, or a group that has been given access to it

In the settings of a project, group rules are displayed in the “Inherited protected environments” table with a link to the owner group in the “Inherited from” column, and a “Deployment tier” badge next to the name. Such a rule cannot be changed or deleted in the project. Use the settings of the owner group.

To create a group rule via API, use /groups/:id/protected_environments with the same parameters as for a project rule. The name parameter must contain only a deployment tier; the API returns 400 for any other value.

Deployment permissions

The “Allowed to deploy” list determines who can run a deployment job for the environment. The list combines roles, individual users, and groups, and a user gets access if they match at least one entry.

Available options:

OptionWho gets accessConditions and limitations
“Developer”Project members with the Developer role or higherAvailable for project rules
“Maintainer”Project members with the Maintainer role or higher—
“Instance admins”Instance administratorsSet only through the API, using "access_level": 60. The protected environment form offers only “Developer” and “Maintainer” for a role
UserThe listed userThe user’s project access must be Developer or higher
GroupMembers of the listed groupThe group must have access to the project. Only members whose project access is Reporter or higher get access. The “Group membership” selector determines which members are taken into account

The “Group membership” selector accepts the following values:

ValueDescription
“Direct members”Only the direct members of the selected group
“Inherited members”Members of the selected group, its parent groups, and groups that have been given access to it

If the “Allowed to deploy” list is empty, the table displays “No one”. In this case:

  • Project members cannot run a deployment job for this environment, regardless of their role.
  • Instance administrators can still deploy.
  • An empty list of any applicable rule blocks deployment to the environment even if another applicable rule allows it.
  • An empty list of a group rule overrides what the project rule permits.

An edit that would leave the list with no entries is rejected. However, the list can become empty if the listed users or groups lose access to the project, for example when a project member is removed or a group’s access is revoked.

A user without permission to deploy to a protected environment cannot perform the following actions on its deployment job:

  • Run it.
  • Cancel it.
  • Retry it.
  • Erase it.

Changes to a role or group membership are taken into account immediately when permissions are checked.

Adding a user to the “Allowed to deploy” list does not raise their role in the project. Access to the environment requires the Reporter role or higher.

Approval rules

An approval rule specifies a subject and the required number of approvals. “Required approvals” accepts a value from 1 to 5. For a user subject the value is always 1, because one user records one decision per rule.

Subjects are selected the same way as in the “Allowed to deploy” list. A subject of an approval rule does not have to be able to deploy. A user who matches an approval rule can approve a deployment without permission to run its job.

A decision belongs to one rule, and the approvals of all rules are combined.

  • A deployment is approved when the required number of approvals has been collected for every rule of every applicable protected environment.
  • A user who matches several rules records a decision for each of them separately. If a project rule and a group rule specify the same subject, approvals for those rules are counted independently, so one person records a decision for each of them.
  • An approval counts while its author still matches the rule it was recorded for. If the author loses the role or the group membership the rule names, the approval stops being counted, and the deployment waits for the remaining approvals.
  • A rejection keeps standing after its author loses the rule.
  • After the first rejection, the deployment counts as rejected, whichever approvals have already been given.

When the rules of a protected environment change, previously recorded decisions are preserved but are counted according to the new rules.

Managing a protected environment

Changing any setting of a protected environment, and stopping or deleting the environment, require the user to be listed in “Allowed to deploy”. The Maintainer role alone does not grant these actions. Instance administrators are not restricted.

The “Clean up environments” action stops stale environments except protected ones. Environments whose name is specified by a project rule, and environments whose tier is specified by an inherited group rule, stay running.

Approving a deployment

While a deployment waits for approvals, its job stays manual and cannot be run. The “Deployment approvals” section on the deployment page shows the progress of every applicable approval rule.

To open the deployment page, go to “Deployments” → “Environments”, open the environment, and select the required deployment in its history. If the deployment waits for approvals, its history shows the “Waiting” status and the “View deployment approvals” button, while the “Environments” list and the page header show the “Needs Approval” badge.

  • Approving via web interface
  • Approving via API

The “Deployment approvals” section displays the following elements:

  • The summary state of the deployment shows the number of approvals still required, for example, “2 of 3 approvals pending”. Once every rule is satisfied, it shows “All required approvals have been given”, and after a rejection it shows “This deployment was rejected and will not proceed”.
  • The progress of each rule shows the number of approvals collected, for example, “Maintainer: 1 of 2 approvals”, and the “Approved”, “Pending approval”, or “Rejected” status. If two rules name the same subject, the “Project” or “Group” badge shows which of them the row belongs to.
  • The “View protected environment settings” link leads to the CI/CD settings of the project.

Below the section, the “Approval history” list shows the recorded decisions, the most recent first: the author, the status, the time, the “Rule” line with the subject of the rule the decision was recorded for, and the comment.

To record a decision:

  1. In “Rule to represent”, select the rule you are voting for. The list contains the rules you match and the rules you have already voted for.
  2. Specify a comment in “Comment (optional)” if needed. The field accepts up to 250 characters.
  3. Click “Approve” or “Reject”.

Deckhouse Code displays “Your decision was recorded.” and updates the progress of the rules.

“Approve” and “Reject” are offered per rule, so the author of a deployment, who cannot approve it, can still record a rejection for a rule.

While the deployment is still waiting for approvals, a previously recorded decision for a rule can be changed from an approval to a rejection. Repeating the decision you already recorded keeps the original record with its comment. The form is no longer displayed after all required approvals have been received or after the deployment is rejected.

To record a decision via API, run the following request:

curl --request POST --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/deployments/<DEPLOYMENT_ID>/approval?status=approved"

Where:

  • <TOKEN>: Token used to authenticate with Deckhouse Code
  • <HOST>: Deckhouse Code instance address
  • <PROJECT_ID>: Project ID
  • <DEPLOYMENT_ID>: Deployment ID

The following parameters can be specified in the request:

ParameterRequiredDescription
statusYesDecision to record: approved or rejected
commentNoComment for the decision, up to 255 characters
represented_asNoName of the rule subject to record the decision for. For a role, use Developers + Maintainers or Maintainers; for a user or group, use its name. If the parameter is omitted, the decision is recorded for the earliest created rule you match. The value is matched case-sensitively as a substring of the subject name

The response contains the recorded decision with its author, status, comment, and time. A request to record a decision that the current user is not allowed to make returns 403. A malformed request or a request for a deployment that no longer waits for approvals returns 400.

The deployment endpoints also return the approval state of a deployment:

  • approval_summary: Progress for each rule.
  • approvals: Recorded decisions.
  • pending_approval_count: Number of approvals still required.

These fields are returned to users who can read the protected environments of the project. For everyone else, they are absent from the response.

The same data is available through the GraphQL API in the approvalSummary, approvals, and pendingApprovalCount fields of Deployment. Each rule in approvalSummary also contains canApprove and canReject for the current user.

In a single GraphQL query, these three fields can be requested for only one deployment. A request for a list of deployments fails with the "approvalSummary" field can be requested only for 1 Deployment(s) at a time. error. To record a decision, use the approveDeployment mutation, which takes the global ID of the rule in approvalRuleId.

Approving your own deployment

If a user’s job created the deployment and the user matches an approval rule, the user can reject the deployment but cannot approve it by default.

To allow this user to approve the deployment, go to “Settings” → “CI/CD” → “Protected environments”. In the “Approval options” section, select “Allow pipeline triggerer to approve deployments” and click “Save changes”. The setting applies to the entire project and is disabled by default.

The author of a deployment is the user of its job, and for a job without a user, the user of the deployment.

Deployment job behavior

Before a runner is assigned to a job that deploys to a protected environment, Deckhouse Code checks the permissions of the job user. If the job has no user, it checks the permissions of the pipeline user.

The result of the check determines what happens to the job.

  • If the applicable rules contain approval rules, Deckhouse Code creates the deployment and switches the job to manual, whichever permissions the pipeline author has. The job cannot be run while approvals are pending or the deployment is rejected.
  • Once every rule has collected its approvals, the job is not started automatically. A user runs it manually. The permission to run the job and the “Allowed to deploy” lists are checked for the user who starts it.
  • If the applicable rules contain no approval rules and the user is not allowed to deploy, the job fails with the “protected environment failure” reason before the deployment is created and before a runner is assigned.
  • A job that deploys to an unprotected environment runs as usual.

The checks are repeated before a runner is assigned. If approvals become required for the job at that point, it returns to the manual state and waits for them.

Rejected deployment

The first recorded rejection fails the deployment job with the “deployment rejected” reason, and the deployment moves to the failed state. A background job applies the state, so it changes with a short delay.

The retry keyword does not restart a rejected deployment job; only a user can retry it. The rejected deployment keeps this status until the job is retried. Retrying creates a new job and a new deployment, which collects approvals again without carrying over decisions from the previous deployment.

Access to protected environments

Available actions depend on the user’s role and the rules of the environment:

ActionRequirements
Reading the protected environments of a project via APITo read the rules, a user must have access to the project environments, while an auditor does not need project membership to read them. In a private or internal project, this requires the Reporter role or higher; in a public project, any role is sufficient (if reading environments is included in the public baseline)
Reading the protected environments of a group via APIThe user is a member of the group, or an auditor
Opening the “Protected environments” section in the project or group settingsThe same role that creates the rules: Maintainer or Owner in the project, Owner in the group
Creating, changing, and deleting the rules of a projectMaintainer or Owner role
Creating, changing, and deleting the rules of a groupOwner role in the group
Running a deployment job for a protected environmentThe user is listed in the “Allowed to deploy” list of every applicable rule
Changing, stopping, or deleting a protected environmentThe user is listed in the “Allowed to deploy” list of every applicable rule
Approving or rejecting a deploymentThe user matches an approval rule of the environment and has read access to the deployment. For the self-approval restriction, see “Approving your own deployment”

Except for auditors, membership is required even in a public project. A user who is neither a project member nor an auditor reads neither its protected environments nor the approval state of its deployments.

Protected environment export and import

A project export contains the protected environments of the project with their “Allowed to deploy” entries and approval rules. Recorded approval decisions are not exported because they belong to a specific deployment, while the export carries only the project configuration.

To find subjects on the target instance, the export stores:

  • The full path of the subject group
  • The full path of the group that owns the project
  • The username of the subject user

On import, a group subject is looked up by its full path, keeping the path relative to the target group, while a user subject is looked up first among the imported members and then by username.

If a subject cannot be matched, or the deprecated required_approval_count field of the export carries any value other than 0, the whole project import is refused. An import that dropped a subject would produce weaker protection than the source configuration.

Audit events

Deckhouse Code records the following audit events for protected environments:

Audit eventDescription
environment_protectedProtected environment was created
environment_unprotectedProtected environment was deleted
protected_environment_deploy_access_level_addedEntry was added to the “Allowed to deploy” list
protected_environment_deploy_access_level_updatedEntry of the “Allowed to deploy” list was changed
protected_environment_deploy_access_level_deletedEntry was removed from the “Allowed to deploy” list
protected_environment_approval_rule_addedApproval rule was added
protected_environment_approval_rule_updatedApproval rule was changed
protected_environment_approval_rule_deletedApproval rule was deleted
deployment_approvedDeployment was approved
deployment_rejectedDeployment was rejected

A configuration change event belongs to the project or group that owns the rule and also contains information about the protected environment and the subject of the entry. For an updated entry, the values before and after the change are also recorded.

Changing a recorded decision creates a new event, while repeating the same decision does not.

Removing a member from the project, and revoking the access of a group to the project, delete the deploy access entries and approval rules of that subject without an event of their own. The removal itself is already recorded.

Troubleshooting

Most troubleshooting cases come down to which rules apply to the environment: the project rule for its name and the group rules for its tier.

Deployment job failed with the protected environment failure reason

The user of the job is not listed in the “Allowed to deploy” list of one of the applicable rules, or the account of this user has been deleted. Check the following:

  • The user must match at least one entry in each “Allowed to deploy” list of the project rule for this environment name and of the group rules for its tier.
  • The “Allowed to deploy” lists are not empty. An empty list denies deployment to everyone.
  • The role of the user in the project is not lower than the role selected in the list.

Deployment job cannot be run

If the environment has approval rules, the job stays manual until every rule collects its approvals. Open the deployment page and check the state of the rules in the “Deployment approvals” section.

The job is also unavailable to a user who is not listed in the “Allowed to deploy” list, even after the deployment is approved.

Environment cannot be edited, stopped, or deleted

Changing any setting of a protected environment, and stopping or deleting it, are available to the users listed in “Allowed to deploy”. Add the user to that list in the rule for this environment name, and in the group rules for its tier.

Approval form is not displayed

Check the following:

  • The deployment waits for approvals. Its job is manual, and the summary state is not “All required approvals have been given” or a rejection.
  • Your account matches an approval rule of this environment, or you have already recorded a decision for one of its rules.
  • The deployment was not created by your own job, or “Allow pipeline triggerer to approve deployments” is enabled in the project. The author of a deployment can reject it without this setting.

Subject cannot be added to a rule

The message “This subject already has a rule for this protected environment” means the role, user, or group is already present in the list you are editing. One subject holds one entry in “Allowed to deploy” and one entry in “Approval rules”. Change the existing entry instead of adding a second one.

How rule changes affect existing decisions

The state of a deployment is computed from the current rules.

If the author of an approval stopped matching the rule the approval was recorded for, the approval stops being counted, and the deployment waits for the remaining approvals. The decision itself is kept and is counted again once the author matches the rule again.

If an approval rule is removed, decisions recorded for it are no longer counted. Adding the same subject again creates a new rule for which approvals are collected from the beginning.

A rejection keeps standing in either case.

Rule of a group is not applied to an environment

Check that the tier of the environment matches the name of the group rule, and that the project belongs to the group that owns the rule or to one of its subgroups. The tier is set by the deployment_tier keyword in the CI/CD configuration file and otherwise derived from the environment name.

Project rule does not apply to an environment with a similar name

The environment name must exactly match the project rule name, including case. Therefore, a rule named Production does not protect the production environment, and a rule named production does not protect production/eu. To protect several environments at once, use a group rule for the corresponding deployment tier.

Inherited rule cannot be changed in a project

Rules displayed in the “Inherited protected environments” table belong to a group. Open the group from the “Inherited from” column and change the rule in its settings.

Additional resources