Skip to content

Commit

Permalink
iam-request-ssh-key-signature: Support cross account requests
Browse files Browse the repository at this point in the history
  • Loading branch information
hamstah committed Jul 25, 2019
1 parent 43ec58f commit baed09c
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 35 deletions.
4 changes: 2 additions & 2 deletions common/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func OpenSession(sessionFlags *SessionFlags) (*session.Session, *aws.Config) {

func AssumeRoleConfig(sessionFlags *SessionFlags, sess *session.Session) *aws.Config {
conf := NewConfig(*sessionFlags.Region)
if *sessionFlags.RoleArn != "" {
if sessionFlags.RoleArn != nil && *sessionFlags.RoleArn != "" {
var creds *credentials.Credentials
creds = stscreds.NewCredentials(sess, *sessionFlags.RoleArn, func(p *stscreds.AssumeRoleProvider) {
if *sessionFlags.RoleExternalID != "" {
Expand All @@ -142,7 +142,7 @@ func AssumeRoleConfig(sessionFlags *SessionFlags, sess *session.Session) *aws.Co
}
})
conf.Credentials = creds
} else if *sessionFlags.MFASerialNumber != "" {
} else if sessionFlags.MFASerialNumber != nil && *sessionFlags.MFASerialNumber != "" {
conf.Credentials = credentials.NewCredentials(&SessionTokenProvider{
SessionFlags: sessionFlags,
Session: sess,
Expand Down
9 changes: 4 additions & 5 deletions iam/request-ssh-key-signature/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os"
"time"

"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hamstah/awstools/common"
Expand Down Expand Up @@ -39,14 +38,14 @@ func main() {
sshPublicKeyBytes, err := ioutil.ReadFile(*sshPublicKeyFilename)
common.FatalOnError(err)

session := session.Must(session.NewSession())
conf := common.AssumeRoleConfig(flags, session)

stsClient := sts.New(session, conf)
userSession := common.NewSession("")
stsClient := sts.New(userSession)

url, err := common.STSGetIdentityURL(stsClient)
common.FatalOnError(err)

session, conf := common.OpenSession(flags)

lambdaPayload := LambdaPayload{
IdentityURL: url,
Environment: *environment,
Expand Down
108 changes: 80 additions & 28 deletions lambda/sign-ssh-key/terraform.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
resource "null_resource" "build" {

triggers = {
build = sha1(file("main.go"))
// Create a secretsmanager secret to store the CA information
locals {
// do not fill these they are just used to initialise the secret structure
ca = {
private_key = ""
private_key_passphrase = ""
public_key = ""
}
}

provisioner "local-exec" {
command = "GOOS=linux GOARCH=amd64 go build -o lambda-sign-ssh-key && chmod +x lambda-sign-ssh-key && zip lambda lambda-sign-ssh-key prod.json"
}
resource "aws_secretsmanager_secret" "ca" {
name = "sign-ssh-key-ca"
}

resource "aws_secretsmanager_secret_version" "ca" {
secret_id = aws_secretsmanager_secret.ca.id
secret_string = jsonencode(local.ca)

lifecycle {
ignore_changes = [secret_string]
}
}

// Create an execution role for the lambda
data "aws_iam_policy_document" "lambda_assume" {
statement {
actions = ["sts:AssumeRole"]
Expand All @@ -26,27 +38,7 @@ resource "aws_iam_role" "ssh_key_signer" {
assume_role_policy = data.aws_iam_policy_document.lambda_assume.json
}

resource "aws_secretsmanager_secret" "ca" {
name = "sign-ssh-key-ca"
}

locals {
ca = {
private_key = ""
private_key_passphrase = ""
public_key = ""
}
}

resource "aws_secretsmanager_secret_version" "ca" {
secret_id = aws_secretsmanager_secret.ca.id
secret_string = jsonencode(local.ca)

lifecycle {
ignore_changes = [secret_string]
}
}

// Create a policy granting read access to the CA secret
data "aws_iam_policy_document" "read_ca_secret" {
statement {
actions = ["secretsmanager:GetSecretValue"]
Expand All @@ -59,11 +51,24 @@ resource "aws_iam_policy" "read_ca_secret" {
policy = data.aws_iam_policy_document.read_ca_secret.json
}

// Attach the policy to the lambda execution role
resource "aws_iam_role_policy_attachment" "read_ca_secret" {
role = aws_iam_role.ssh_key_signer.name
policy_arn = aws_iam_policy.read_ca_secret.arn
}

// Build the lambda binary
resource "null_resource" "build" {

triggers = {
build = sha1(file("main.go"))
}

provisioner "local-exec" {
command = "GOOS=linux GOARCH=amd64 go build -o lambda-sign-ssh-key && chmod +x lambda-sign-ssh-key && zip lambda lambda-sign-ssh-key prod.json"
}
}

resource "aws_lambda_function" "lambda" {
filename = "${path.module}/lambda.zip"
function_name = "sign-ssh-key"
Expand All @@ -77,3 +82,50 @@ resource "aws_lambda_function" "lambda" {
output "lambda_arn" {
value = aws_lambda_function.lambda.arn
}

// Create a role to be assumed by users requesting signatures
variable "ssh_signature_requester_account_ids" {
type = list(string)
default = []
}

data "aws_iam_policy_document" "requester_assume" {
statement {
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = var.ssh_signature_requester_account_ids
}
}
}

resource "aws_iam_role" "ssh_key_signature_requester" {
name = "ssh-key-signature-requester"
assume_role_policy = data.aws_iam_policy_document.requester_assume.json
}

output "ssh_key_signature_requester_arn" {
value = aws_iam_role.ssh_key_signature_requester.arn
}

// Create a policy to allow the role to call the lambda
data "aws_iam_policy_document" "ssh_key_signature_request" {
statement {
actions = ["lambda:InvokeFunction"]
resources = [
aws_lambda_function.lambda.arn
]
}
}

resource "aws_iam_policy" "ssh_key_signature_request" {
name = "ssh-key-signature-request"
policy = data.aws_iam_policy_document.ssh_key_signature_request.json
}

// Attach the policy to the requester role
resource "aws_iam_role_policy_attachment" "ssh_key_signature_request" {
role = aws_iam_role.ssh_key_signature_requester.name
policy_arn = aws_iam_policy.ssh_key_signature_request.arn
}

0 comments on commit baed09c

Please sign in to comment.