Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions docs/docs/40-operator-guide/40-security/60-promotion-pod-identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
description: Learn how to set up workload identity for promotion pods
sidebar_label: Promotion Pod Identity
---

<span class="tag professional"></span>
<span class="tag beta"></span>

:::info

This document describes how to set workload identity for promotions run by
Promotion Controller in Kargo versions v1.11 and above.

Promotion Controller is only available in Kargo on the [Akuity Platform](https://akuity.io/akuity-platform)
and requires use of self-hosted agent.

:::

# Promotion Pod identity

## Background

Most workload identity tools are using pod serviceaccounts to provision access for tools running in the pod.

When using Promotion Controller, each promotion is run as a pod with steps running as containers in this pod.
This makes it possible for steps to access workload identity for the promotion pod and have required permissions.

Promotion pods are assigned `kargo-promotion-orchestrator` serviceaccount by default.
While it is technically possible to assign federated identity (e.g. IRSA) to `kargo-promotion-orchestrator`
serviceaccount, Akuity Platform may override these setting for example when upgrading or configuring Kargo.

Also using the same serviceaccount to access multiple different roles for different promotions/stages/steps is not the
best approach from security or configuration point of view.

## Promotion decorator annotation for Stages

Since version `1.11`, Kargo supports decorator annotations for `Stage` resources, which will change how
Promotion Controller runs promotion pods.

Supported decorator annotations are:

- `ee.kargo.akuity.io/promotion-sa` - **overrides** the serviceaccount used to run the promotion pod
- `ee.kargo.akuity.io/promotion-labels` - **extends** the labels used in the promotion pod
- `ee.kargo.akuity.io/promotion-annotations` - **extends** the annotations used in the promotion pod

Each annotation can be set separately. Empty values have no effect.

:::warning

If not empty, `promotion-sa` must be a valid serviceaccount in the agent namespace.
`promotion-labels` must be a JSON string with valid k8s labels.
`promotion-annotations` must be a JSON string with valid k8s annotations.

Promotion will error if values in these annotations are invalid.

:::

## Example using decorators for a stage

For example if we have a custom step accessing S3:

```
apiVersion: ee.kargo.akuity.io/v1alpha1
kind: CustomPromotionStep
metadata:
name: aws-s3-ls
spec:
image: amazon/aws-cli
command: [
"sh",
"-c",
"mkdir -p $HOME; aws s3 ls s3://{{ config.bucket }}"]
env:
- name: HOME ## HOME is required to run as non-root
value: /tmp/home
```

And we have a serviceaccount configured to access a role with S3 access:
```
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/access-s3
labels:
app.kubernetes.io/managed-by: eksctl
name: s3-access
namespace: akuity
```

We can configure a stage to use this serviceaccount and access the role:

```
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: my-stage
namespace: kargo-demo
annotations:
ee.kargo.akuity.io/promotion-sa: s3-access
spec:
promotionTemplate:
spec:
steps:
- as: list s3
config:
bucket: my_bucket_name
uses: aws-s3-ls
requestedFreight:
...
```

## Known limitations

Because entire promotion is running in a single pod, all steps in the pod will have the same identity and will get the same
access provisioned into them.

This means steps within the same promotion cannot use different serviceaccounts. If they need different permissions, those
need to be attached to the same serviceaccount.

Some builtin steps require serviceaccount to have specific k8s role bindings.
Namely when running `argocd-update` with incluster ArgoCD (on the same cluster as promotion controller agent),
the serviceaccount used in promotion must be bound to `kargo-promotion-token-manager` role.

You can create a binding for serviceaccount like this:
```
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kargo-promotion-token-manager-orchestrator
namespace: akuity ## Promotion namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: "kargo-promotion-token-manager"
subjects:
- kind: ServiceAccount
namespace: akuity ## Promotion namespace
name: <my-service-account>
```

**NOTE** this only applies to a setup where ArgoCD runs in the same cluster as promotion pods.
3 changes: 3 additions & 0 deletions docs/docs/50-user-guide/60-reference-docs/70-annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ programmatically with Kargo.
| `rbac.kargo.akuity.io/managed` | `ServiceAccount`, `Role`, `RoleBinding` | `"true"` | Permits the UI or CLI (via the API server) to programmatically manage trios of `ServiceAccount`, `Role`, and `RoleBinding` resources via Kargo's own ["roles" abstraction](../50-security/20-access-controls/index.md#managing-mappings-and-permissions). Omit this annotation if you wish to exclusively manage these resources [declaratively](../50-security/20-access-controls/index.md#managing-kargo-roles-declaratively). |
| `kargo.akuity.io/replicate-to` | `Secret`, `ConfigMap` (in the shared resources namespace) | `"*"` | Enables automatic replication of the resource to all Project namespaces. For more details, see the [Replicating Shared Resources](../../40-operator-guide/40-security/40-managing-secrets.md#replicating-shared-resources-to-project-namespaces) section of the Operator Guide. |
| `kargo.akuity.io/replicated-at` | `Secret`, `ConfigMap` (replicated copies) | UTC timestamp | Records when the resource was last replicated from the source. Managed by the system. |
| `ee.kargo.akuity.io/promotion-sa` | `Stage` | String `ServiceAccount` name in promotion namespace | Overrides default serviceaccount for promotion pods ran by Promotion Controller (Kargo EE only) |
| `ee.kargo.akuity.io/promotion-labels` | `Stage` | JSON string encoding valid K8s labels | Extends labels for promotion pods ran by Promotion Controller (Kargo EE only) |
| `ee.kargo.akuity.io/promotion-annotations` | `Stage` | JSON string encoding valid K8s annotations | Extends annotations for promotion pods ran by Promotion Controller (Kargo EE only) |

## Labels

Expand Down
Loading