Skip to content

Commit 79e18ba

Browse files
committed
terraform-iam: configure OIDC for NixOS/nix releases
1 parent 0ea7377 commit 79e18ba

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
}
6+
}
7+
}
8+
9+
variable "subject_filter" {
10+
type = list(string)
11+
}
12+
13+
data "aws_caller_identity" "current" {}
14+
15+
data "aws_iam_openid_connect_provider" "github_actions" {
16+
url = "https://token.actions.githubusercontent.com"
17+
}
18+
19+
data "aws_iam_policy_document" "assume_github_actions" {
20+
21+
statement {
22+
effect = "Allow"
23+
actions = ["sts:AssumeRoleWithWebIdentity"]
24+
25+
principals {
26+
type = "Federated"
27+
identifiers = [data.aws_iam_openid_connect_provider.github_actions.arn]
28+
}
29+
30+
condition {
31+
test = "StringLike"
32+
variable = "token.actions.githubusercontent.com:sub"
33+
values = var.subject_filter
34+
}
35+
}
36+
}
37+
38+
output "json" {
39+
value = data.aws_iam_policy_document.assume_github_actions.json
40+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
}
6+
}
7+
}
8+
9+
variable "target_account_id" {
10+
description = "AWS account ID where the reserved SSO roles exist (the target account)."
11+
type = string
12+
}
13+
14+
variable "sso_region" {
15+
description = "Region of the AWS IAM Identity Center instance."
16+
type = string
17+
default = "eu-north-1"
18+
}
19+
20+
variable "permission_set_name" {
21+
description = "Name of the IAM Identity Center permission set (without the AWSReservedSSO_ prefix)."
22+
type = string
23+
}
24+
25+
locals {
26+
reserved_role_pattern = format(
27+
"arn:aws:iam::%s:role/aws-reserved/sso.amazonaws.com/%s/AWSReservedSSO_%s_*",
28+
var.target_account_id,
29+
var.sso_region,
30+
var.permission_set_name,
31+
)
32+
}
33+
34+
data "aws_iam_policy_document" "this" {
35+
statement {
36+
effect = "Allow"
37+
actions = ["sts:AssumeRole"]
38+
principals {
39+
type = "AWS"
40+
identifiers = [format("arn:aws:iam::%s:root", var.target_account_id)]
41+
}
42+
condition {
43+
test = "ArnLike"
44+
variable = "aws:PrincipalArn"
45+
values = [local.reserved_role_pattern]
46+
}
47+
}
48+
}
49+
50+
output "json" {
51+
value = data.aws_iam_policy_document.this.json
52+
}

terraform-iam/nix_repo_oidc.tf

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# In this document we configure OIDC from GitHub to allow automatically
2+
# publishing NixOS/nix releases using GitHub Actions.
3+
#
4+
# This means that everyone with merge rights in the Nix repo can publish
5+
# releases (with a public trail).
6+
7+
resource "aws_iam_openid_connect_provider" "github_actions" {
8+
url = "https://token.actions.githubusercontent.com"
9+
10+
client_id_list = ["sts.amazonaws.com"]
11+
thumbprint_list = [
12+
# https://github.com/aws-actions/configure-aws-credentials/issues/357#issuecomment-1626357333
13+
"6938fd4d98bab03faadb97b34396831e3780aea1",
14+
]
15+
}
16+
17+
import {
18+
to = aws_iam_openid_connect_provider.github_actions
19+
id = format(
20+
"arn:aws:iam::%s:oidc-provider/token.actions.githubusercontent.com",
21+
data.aws_caller_identity.current.account_id,
22+
)
23+
}
24+
25+
data "aws_iam_policy_document" "nix_release" {
26+
statement {
27+
effect = "Allow"
28+
actions = [
29+
"s3:GetObject",
30+
"s3:PutObject"
31+
]
32+
# Only allow uploading in the /nix/ prefix in the bucket
33+
resources = ["arn:aws:s3:::nix-releases/nix/*"]
34+
}
35+
36+
statement {
37+
effect = "Allow"
38+
actions = [
39+
"s3:ListBucket",
40+
"s3:ListBucketMultipartUploads"
41+
]
42+
resources = ["arn:aws:s3:::nix-releases"]
43+
condition {
44+
test = "StringLike"
45+
variable = "s3:prefix"
46+
values = ["nix/*"]
47+
}
48+
}
49+
50+
statement {
51+
effect = "Allow"
52+
actions = [
53+
"s3:PutObject"
54+
]
55+
# The release also publishes the install script when it's the latest
56+
# release.
57+
resources = ["arn:aws:s3:::nix-channels/nix-latest/install"]
58+
}
59+
60+
statement {
61+
effect = "Allow"
62+
actions = [
63+
"s3:ListBucket"
64+
]
65+
resources = ["arn:aws:s3:::nix-channels"]
66+
condition {
67+
test = "StringLike"
68+
variable = "s3:prefix"
69+
values = ["nix-latest/*"]
70+
}
71+
}
72+
}
73+
74+
resource "aws_iam_policy" "nix_release" {
75+
name = "nix-release"
76+
policy = data.aws_iam_policy_document.nix_release.json
77+
}
78+
79+
data "aws_caller_identity" "current" {}
80+
81+
module "assume_nix_releases_permission" {
82+
source = "./assume_identity_center_permission_policy"
83+
target_account_id = data.aws_caller_identity.current.account_id
84+
permission_set_name = "NixReleases"
85+
sso_region = "eu-north-1"
86+
}
87+
88+
module "assume_nix_release" {
89+
source = "./assume_github_actions_policy_document"
90+
91+
# Only allow to assume this role in the NixOS/nix repo, and while running
92+
# in the "releases" environment.
93+
subject_filter = ["repo:NixOS/nix:environment:releases"]
94+
}
95+
96+
data "aws_iam_policy_document" "assume_nix_release" {
97+
source_policy_documents = [
98+
module.assume_nix_releases_permission.json,
99+
module.assume_nix_release.json,
100+
]
101+
}
102+
103+
resource "aws_iam_role" "nix_release" {
104+
name = "nix-release"
105+
assume_role_policy = data.aws_iam_policy_document.assume_nix_release.json
106+
}
107+
108+
resource "aws_iam_role_policy_attachment" "nix_release_managed_policy" {
109+
role = aws_iam_role.nix_release.name
110+
policy_arn = aws_iam_policy.nix_release.arn
111+
}
112+
113+
output "nix_release_role_arn" {
114+
value = aws_iam_role.nix_release.arn
115+
}

0 commit comments

Comments
 (0)