Skip to content

Commit bcdf931

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

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
}
6+
}
7+
}
8+
9+
variable "sso_account_id" {
10+
description = "AWS account ID where the AdministratorAccess permission set lives."
11+
type = string
12+
}
13+
14+
variable "sso_region" {
15+
description = "Region of the AWS SSO instance."
16+
type = string
17+
default = "eu-north-1"
18+
}
19+
20+
locals {
21+
administrator_role_pattern = format(
22+
"arn:aws:iam::%s:role/aws-reserved/sso.amazonaws.com/%s/AWSReservedSSO_AWSAdministratorAccess_*",
23+
var.sso_account_id,
24+
var.sso_region,
25+
)
26+
}
27+
28+
data "aws_iam_policy_document" "this" {
29+
statement {
30+
effect = "Allow"
31+
actions = ["sts:AssumeRole"]
32+
principals {
33+
type = "AWS"
34+
identifiers = [format("arn:aws:iam::%s:root", var.sso_account_id)]
35+
}
36+
condition {
37+
test = "ArnLike"
38+
variable = "aws:PrincipalArn"
39+
values = [local.administrator_role_pattern]
40+
}
41+
}
42+
}
43+
44+
output "json" {
45+
value = data.aws_iam_policy_document.this.json
46+
}
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+
}

terraform-iam/nix_repo_oidc.tf

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
data "aws_iam_policy_document" "nix_release" {
8+
statement {
9+
effect = "Allow"
10+
actions = [
11+
"s3:GetObject",
12+
"s3:PutObject"
13+
]
14+
# Only allow uploading in the /nix/ prefix in the bucket
15+
resources = ["arn:aws:s3:::nix-releases/nix/*"]
16+
}
17+
18+
statement {
19+
effect = "Allow"
20+
actions = [
21+
"s3:ListBucket",
22+
"s3:ListBucketMultipartUploads"
23+
]
24+
resources = ["arn:aws:s3:::nix-releases"]
25+
condition {
26+
test = "StringLike"
27+
variable = "s3:prefix"
28+
values = ["nix/*"]
29+
}
30+
}
31+
32+
statement {
33+
effect = "Allow"
34+
actions = [
35+
"s3:PutObject"
36+
]
37+
# The release also publishes the install script when it's the latest
38+
# release.
39+
resources = ["arn:aws:s3:::nix-channels/nix-latest/install"]
40+
}
41+
42+
statement {
43+
effect = "Allow"
44+
actions = [
45+
"s3:ListBucket"
46+
]
47+
resources = ["arn:aws:s3:::nix-channels"]
48+
condition {
49+
test = "StringLike"
50+
variable = "s3:prefix"
51+
values = ["nix-latest/*"]
52+
}
53+
}
54+
}
55+
56+
resource "aws_iam_policy" "nix_release" {
57+
name = "nix-release"
58+
policy = data.aws_iam_policy_document.nix_release.json
59+
}
60+
61+
data "aws_caller_identity" "current" {}
62+
63+
module "assume_administrator_access" {
64+
source = "./assume_administrator_access_policy_document"
65+
sso_account_id = data.aws_caller_identity.current.account_id
66+
sso_region = "eu-north-1"
67+
}
68+
69+
module "assume_nix_release" {
70+
source = "./assume_github_actions_policy_document"
71+
72+
# Only allow to assume this role in the NixOS/nix repo, and while running
73+
# in the "releases" environment.
74+
subject_filter = ["repo:NixOS/nix:environment:releases"]
75+
}
76+
77+
data "aws_iam_policy_document" "assume_nix_release" {
78+
source_policy_documents = [
79+
module.assume_administrator_access.json,
80+
module.assume_nix_release.json,
81+
]
82+
}
83+
84+
resource "aws_iam_role" "nix_release" {
85+
name = "nix-release"
86+
assume_role_policy = data.aws_iam_policy_document.assume_nix_release.json
87+
managed_policy_arns = [aws_iam_policy.nix_release.arn]
88+
}
89+
90+
output "nix_release_role_arn" {
91+
value = aws_iam_role.nix_release.arn
92+
}

0 commit comments

Comments
 (0)