Skip to content
Draft
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
1 change: 0 additions & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@
]
},
{
"allowedVersions": "< 3.0.0",
"matchPackageNames": [
"https://gitlab.nic.cz/labs/bird.git"
]
Expand Down
1 change: 1 addition & 0 deletions .kres.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ spec:
- amazon-ena
- amdgpu
- amd-ucode
- aws-iam-authenticator
- binfmt-misc
- bird2
- bnx2-bnx2x
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ If the field is marked as `Needs Maintainer`, it means that the package is curre
| amazon-ena | Sidero Labs | NA |
| amdgpu | Sidero Labs | NA |
| amd-ucode | Sidero Labs | NA |
| aws-iam-authenticator | Fábio Matavelli | [fabiomatavelli](https://github.com/fabiomatavelli) |
| binfmt-misc | Serge Logvinov | [sergelogvinov](https://github.com/sergelogvinov) |
| bnx2-bnx2x | Sidero Labs | NA |
| btrfs | Enno Boland | [Gottox](https://github.com/Gottox) |
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-12-24T16:04:12Z by kres 26be706.
# Generated on 2026-01-02T15:53:16Z by kres 8a4aebf.

# common variables

Expand Down Expand Up @@ -37,6 +37,7 @@ PLATFORM ?= linux/amd64,linux/arm64
PROGRESS ?= auto
PUSH ?= false
CI_ARGS ?=
WITH_BUILD_DEBUG ?=
BUILD_ARGS = --build-arg=SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH)
BUILD_ARGS += --build-arg=TAG="$(TAG)"
BUILD_ARGS += --build-arg=PKGS="$(PKGS)"
Expand All @@ -63,6 +64,7 @@ IMAGE_SIGNER_RELEASE ?= v0.1.1
TARGETS = amazon-ena
TARGETS += amdgpu
TARGETS += amd-ucode
TARGETS += aws-iam-authenticator
TARGETS += binfmt-misc
TARGETS += bird2
TARGETS += bnx2-bnx2x
Expand Down Expand Up @@ -189,6 +191,10 @@ respectively.

endef

ifneq (, $(filter $(WITH_BUILD_DEBUG), t true TRUE y yes 1))
BUILD := BUILDX_EXPERIMENTAL=1 docker buildx debug --invoke /bin/sh --on error build
endif

all: $(TARGETS) ## Builds all targets defined.

$(ARTIFACTS): ## Creates artifacts directory.
Expand Down
173 changes: 173 additions & 0 deletions container-runtime/aws-iam-authenticator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# AWS IAM Authenticator Extension

This extension provides the [aws-iam-authenticator](https://github.com/kubernetes-sigs/aws-iam-authenticator) for Talos Linux. The AWS IAM Authenticator allows you to use AWS IAM credentials to authenticate to your Kubernetes cluster, eliminating the need to manage static kubeconfig files.

## Overview

The extension includes:
- The `aws-iam-authenticator` binary for server-side authentication
- A custom init wrapper that generates certificates and kubeconfig files on node startup
- Support for configurable init parameters via environment variables

When installed, the extension runs during node initialization to generate the necessary certificates, private keys, and webhook kubeconfig files required for the kube-apiserver to authenticate users via AWS IAM.

## Installation

See [Installing Extensions](https://github.com/siderolabs/extensions#installing-extensions).

## Configuration

### 1. Extension Service Configuration

Configure the extension via `ExtensionServiceConfig` document. Below is an example with all available environment variables:

```yaml
# aws-iam-authenticator-config.yaml
---
apiVersion: v1alpha1
kind: ExtensionServiceConfig
name: aws-iam-authenticator
environment:
# Required: Cluster identifier (must match the cluster ID used by clients)
- CLUSTER_ID=my-cluster
# Optional: Hostname for self-signed certificates (default: localhost)
- HOSTNAME=kubernetes.example.com
# Optional: IP address to bind the server to (default: 127.0.0.1)
- ADDRESS=127.0.0.1
# Optional: Path to configuration file
- CONFIG_FILE=/usr/local/lib/aws-iam-authenticator/config.yaml
# Optional: Log format (text or json)
- LOG_FORMAT=json
```

Then apply the patch to your node's MachineConfigs:
```bash
talosctl patch mc -p @aws-iam-authenticator-config.yaml
```

You can verify that it is in place with the following command:
```bash
talosctl get extensionserviceconfigs

NODE NAMESPACE TYPE ID VERSION
mynode runtime ExtensionServiceConfig aws-iam-authenticator 1
```

**Environment Variables:**

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `CLUSTER_ID` | Yes | - | Unique cluster identifier. Must match the `-i` flag used by clients to prevent replay attacks across clusters. |
| `HOSTNAME` | No | `localhost` | Hostname used when generating self-signed certificates. Set this to your API server's hostname. |
| `ADDRESS` | No | `127.0.0.1` | IP address the authenticator server will bind to. Use `127.0.0.1` for local-only or `0.0.0.0` to listen on all interfaces. |
| `CONFIG_FILE` | No | - | Path to a configuration file for advanced settings (role mappings, backend mode, etc.). |
| `LOG_FORMAT` | No | `text` | Log output format. Options: `text` or `json`. |

### 2. Kube-APIServer Configuration

After installing the extension, you must configure the kube-apiserver to use the webhook authentication method. Add the following to your Talos cluster configuration:

```yaml
cluster:
apiServer:
extraArgs:
authentication-token-webhook-config-file: /usr/local/lib/aws-iam-authenticator/kubeconfig.yaml
extraVolumes:
- hostPath: /usr/local/lib/aws-iam-authenticator
mountPath: /usr/local/lib/aws-iam-authenticator
readOnly: true
```

**What this does:**
- `authentication-token-webhook-config-file`: Tells the kube-apiserver to validate bearer tokens using the webhook configuration generated by aws-iam-authenticator
- The volume mount gives the API server access to the generated kubeconfig and certificates

### 3. AWS IAM Authenticator Server DaemonSet

After the init process generates the certificates and kubeconfig, you need to deploy the aws-iam-authenticator server as a DaemonSet on control plane nodes.

**Important:** Make sure to configure the DaemonSet with the following requirements:
- Point `--config`, `--state-dir`, and `--generate-kubeconfig` to `/usr/local/lib/aws-iam-authenticator`
- Include the `--kubeconfig-pregenerated=true` flag since the extension has already generated the kubeconfig
- Mount `/usr/local/lib/aws-iam-authenticator` from the host

See [example-daemonset.yaml](example-daemonset.yaml) for a complete working example.

### 4. Client Configuration and IAM Role Mapping

For client-side configuration and IAM role/user mapping to Kubernetes RBAC groups, please refer to the official documentation:

- [Client Setup - Installing aws-iam-authenticator](https://github.com/kubernetes-sigs/aws-iam-authenticator#4-set-up-kubectl-to-use-authentication-tokens-provided-by-aws-iam-authenticator-for-kubernetes)
- [IAM Role Mapping Configuration](https://github.com/kubernetes-sigs/aws-iam-authenticator#full-configuration-format)

## How It Works

1. **Initialization**: When a Talos node boots, the extension service runs the init wrapper which executes `aws-iam-authenticator init`
2. **Certificate Generation**: The init command generates:
- Self-signed certificates for the webhook server
- A webhook kubeconfig file at `/usr/local/lib/aws-iam-authenticator/kubeconfig.yaml`
3. **API Server Integration**: The kube-apiserver uses the generated kubeconfig to validate authentication tokens via webhook
4. **Authentication Flow**:
- Client runs `aws-iam-authenticator token -i <cluster-id>` to generate a token
- Client sends the token to the API server in the Authorization header
- API server forwards the token to the webhook endpoint
- The authenticator validates the AWS signature and returns the user identity and groups
- API server applies RBAC based on the returned groups

## Service Management

The extension service appears in the service list with the `ext-` prefix. Since the init process runs once and exits, the service will show as "Finished":

```bash
$ talosctl services
NODE SERVICE STATE HEALTH LAST CHANGE
172.20.0.5 ext-aws-iam-authenticator Finished ? 1m38s ago
```

View detailed service information:

```bash
$ talosctl service ext-aws-iam-authenticator
```

View service logs:

```bash
$ talosctl logs ext-aws-iam-authenticator
```

## Troubleshooting

### Check Generated Files

Verify that the init process generated the necessary files:

```bash
$ talosctl ls /usr/local/lib/aws-iam-authenticator/
.
..
cert.pem
key.pem
kubeconfig.yaml
```

### Verify Cluster ID

Ensure the `CLUSTER_ID` in your extension configuration matches the `-i` parameter used by clients:

```bash
$ talosctl logs ext-aws-iam-authenticator | grep "executing"
executing: /usr/local/bin/aws-iam-authenticator [init -i=my-cluster]
```

### Common Issues

- **Authentication fails**: Verify cluster IDs match between server and client
- **Permission denied**: Check that the API server can read `/usr/local/lib/aws-iam-authenticator/kubeconfig.yaml`
- **Certificate errors**: Ensure `HOSTNAME` matches your API server's hostname if using TLS

## References

- [aws-iam-authenticator GitHub Repository](https://github.com/kubernetes-sigs/aws-iam-authenticator)
- [EKS Anywhere - IAM Authentication](https://anywhere.eks.amazonaws.com/docs/clustermgmt/security/cluster-iam-auth/)
- [AWS Best Practices - Identity and Access Management](https://docs.aws.amazon.com/eks/latest/best-practices/identity-and-access-management.html)
24 changes: 24 additions & 0 deletions container-runtime/aws-iam-authenticator/aws-iam-authenticator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: aws-iam-authenticator
depends:
- service: cri
- network:
- addresses
- connectivity
- etcfiles
- configuration: true
- time: true
container:
entrypoint: ./init
environment:
- PATH=/sbin:/usr/local/bin
security:
writeableRootfs: true
mounts:
- destination: /usr/local/lib/aws-iam-authenticator
type: bind
source: /usr/local/lib/aws-iam-authenticator
options:
- rbind
- rshared
- rw
restart: never
125 changes: 125 additions & 0 deletions container-runtime/aws-iam-authenticator/example-daemonset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: aws-iam-authenticator
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: aws-iam-authenticator
rules:
- apiGroups:
- iamauthenticator.k8s.aws
resources:
- iamidentitymappings
verbs:
- get
- list
- watch
- apiGroups:
- iamauthenticator.k8s.aws
resources:
- iamidentitymappings/status
verbs:
- patch
- update
- apiGroups:
- ""
resources:
- events
verbs:
- create
- update
- patch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
- aws-auth
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: aws-iam-authenticator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: aws-iam-authenticator
subjects:
- kind: ServiceAccount
name: aws-iam-authenticator
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
namespace: kube-system
name: aws-iam-authenticator
labels:
k8s-app: aws-iam-authenticator
spec:
selector:
matchLabels:
k8s-app: aws-iam-authenticator
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
k8s-app: aws-iam-authenticator
spec:
serviceAccountName: aws-iam-authenticator
hostNetwork: true
nodeSelector:
node-role.kubernetes.io/control-plane: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
- key: CriticalAddonsOnly
operator: Exists
priorityClassName: system-cluster-critical
containers:
- name: aws-iam-authenticator
image: 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-iam-authenticator:v0.7.10
args:
- server
# IMPORTANT: Point to the pre-generated files from the extension
- --config=/usr/local/lib/aws-iam-authenticator/config.yaml
- --state-dir=/usr/local/lib/aws-iam-authenticator
- --generate-kubeconfig=/usr/local/lib/aws-iam-authenticator/kubeconfig.yaml
# IMPORTANT: Use pre-generated kubeconfig from the extension init process
- --kubeconfig-pregenerated=true
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
resources:
requests:
memory: 20Mi
cpu: 10m
limits:
memory: 20Mi
cpu: 100m
volumeMounts:
- name: state
mountPath: /usr/local/lib/aws-iam-authenticator/
volumes:
- name: state
hostPath:
path: /usr/local/lib/aws-iam-authenticator/
type: Directory
10 changes: 10 additions & 0 deletions container-runtime/aws-iam-authenticator/manifest.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: v1alpha1
metadata:
name: aws-iam-authenticator
version: "{{ .VERSION }}"
author: Fábio Matavelli
description: |
[{{ .TIER }}] This system extension provides aws-iam-authenticator init process to generate certificates and kubeconfig for AWS IAM authentication with Kubernetes.
compatibility:
talos:
version: ">= v1.11.0"
Loading