Skip to content

Commit

Permalink
add temporary credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Vlasic committed Jul 29, 2021
1 parent 5127ec0 commit ff98f78
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 29 deletions.
60 changes: 60 additions & 0 deletions api/data/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package data

import (
"context"
"fmt"
"log"

"github.com/atoz-technology/mantil-backend/internal/mantil"
"github.com/atoz-technology/mantil-backend/internal/stream"
)

type Data struct {
}

type DataRequest struct {
ProjectName string
Token string
}

type DataResponse struct {
Project *mantil.Project
}

func (f *Data) Invoke(ctx context.Context, req *DataRequest) (*DataResponse, error) {
return f.Project(ctx, req)
}

func (f *Data) Project(ctx context.Context, req *DataRequest) (*DataResponse, error) {
if req.ProjectName == "" || req.Token == "" {
return nil, fmt.Errorf("bad request")
}

var p *mantil.Project
err := stream.LambdaLogStream(ctx, func() error {
var err error
p, err = mantil.LoadProject(req.ProjectName)
if err != nil {
log.Printf("%v", err)
return err
}

if p.Token != req.Token {
log.Printf("access denied - %s", p.Token)
return fmt.Errorf("access denied")
}
return nil
})
if err != nil {
log.Printf("%v", err)
return nil, err
}

return &DataResponse{
Project: p,
}, nil
}

func New() *Data {
return &Data{}
}
17 changes: 14 additions & 3 deletions api/security/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package security
import (
"context"
"fmt"
"log"

"github.com/atoz-technology/mantil-backend/internal/mantil"
"github.com/atoz-technology/mantil-backend/internal/security"
"github.com/atoz-technology/mantil-backend/internal/stream"
stsTypes "github.com/aws/aws-sdk-go-v2/service/sts/types"
)

type Security struct{}
Expand All @@ -22,24 +25,32 @@ type SecurityResponse struct {
}

func (f *Security) Invoke(ctx context.Context, req *SecurityRequest) (*SecurityResponse, error) {
return f.FederationToken(ctx, req)
return f.Credentials(ctx, req)
}

func (f *Security) FederationToken(ctx context.Context, req *SecurityRequest) (*SecurityResponse, error) {
func (f *Security) Credentials(ctx context.Context, req *SecurityRequest) (*SecurityResponse, error) {
if req.ProjectName == "" || req.Token == "" {
return nil, fmt.Errorf("bad request")
}

p, err := mantil.LoadProject(req.ProjectName)
if err != nil {
log.Printf("%v", err)
return nil, err
}
if p.Token != req.Token {
log.Printf("access denied - %s - %s", p.Token, req.Token)
return nil, fmt.Errorf("access denied")
}

creds, err := security.FederationToken(p)
var creds *stsTypes.Credentials
err = stream.LambdaLogStream(ctx, func() error {
var err error
creds, err = security.Credentials(p)
return err
})
if err != nil {
log.Printf("%v", err)
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion config/mantil.local.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Bucket":"mantil-project-try-mantil-backend","GithubOrg":"atoz-technology"}
{"Bucket": "mantil-project-try-mantil-backend", "Name":"mantil-backend","GithubOrg":"atoz-technology"}
1 change: 1 addition & 0 deletions functions/data/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data
11 changes: 11 additions & 0 deletions functions/data/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"github.com/atoz-technology/mantil-backend/api/data"
"github.com/atoz-technology/mantil.go"
)

func main() {
var api = data.New()
mantil.LambdaHandler(api)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/aws/aws-lambda-go v1.25.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.7.1
github.com/aws/aws-sdk-go-v2/config v1.5.0
github.com/aws/aws-sdk-go-v2/service/iam v1.7.0
github.com/aws/aws-sdk-go-v2/service/lambda v1.5.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.11.1
github.com/aws/aws-sdk-go-v2/service/sts v1.6.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.3.0/go.mod h1:2LAuqPx1I6jNfaGDu
github.com/aws/aws-sdk-go-v2/internal/ini v1.1.0/go.mod h1:qGQ/9IfkZonRNSNLE99/yBJ7EPA/h8jlWEqtJCcaj+Q=
github.com/aws/aws-sdk-go-v2/internal/ini v1.1.1 h1:SDLwr1NKyowP7uqxuLNdvFZhjnoVWxNv456zAp+ZFjU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.1.1/go.mod h1:Zy8smImhTdOETZqfyn01iNOe0CNggVbPjCajyaz6Gvg=
github.com/aws/aws-sdk-go-v2/service/iam v1.7.0 h1:DgL3Rifvc2EhkSbrq7dDdMNXPA4IXbXH6VR/pBLzACI=
github.com/aws/aws-sdk-go-v2/service/iam v1.7.0/go.mod h1:SR0ZnnmMCxLVZpWlODnStM3b+mOZXiviPtX6aCJpukM=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.1 h1:s/uV8UyMB4UcO0ERHxG9BJhYJAD9MiY0QeYvJmlC7PE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.1/go.mod h1:v33JQ57i2nekYTA70Mb+O18KeH4KqhdqxTJZNK1zdRE=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.0/go.mod h1:a7XLWNKuVgOxjssEF019IiHPv35k8KHBaWv/wJAfi2A=
Expand Down
12 changes: 6 additions & 6 deletions internal/assets/bindata.go

Large diffs are not rendered by default.

Binary file modified internal/assets/terraform/modules/dynamodb.zip
Binary file not shown.
Binary file modified internal/assets/terraform/modules/funcs.zip
Binary file not shown.
70 changes: 64 additions & 6 deletions internal/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/lambda"
"github.com/aws/aws-sdk-go-v2/service/s3"
s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types"
Expand Down Expand Up @@ -184,18 +185,19 @@ func (a *AWS) UpdateLambdaFunctionCodeFromS3(function, bucket, key string) error
return nil
}

func (a *AWS) GetProjectToken(name, policy string) (*stsTypes.Credentials, error) {
gfti := &sts.GetFederationTokenInput{
func (a *AWS) RoleCredentials(name, role, policy string) (*stsTypes.Credentials, error) {
ari := &sts.AssumeRoleInput{
RoleArn: aws.String(role),
RoleSessionName: aws.String(name),
DurationSeconds: aws.Int32(900),
Name: aws.String(name),
Policy: aws.String(policy),
}

gfto, err := a.stsClient.GetFederationToken(context.TODO(), gfti)
creds, err := a.stsClient.AssumeRole(context.TODO(), ari)
if err != nil {
return nil, fmt.Errorf("could not get project token - %v", err)
return nil, err
}
return gfto.Credentials, nil
return creds.Credentials, nil
}

func (a *AWS) UpdateLambdaFunctionCodeImage(function, image string) error {
Expand All @@ -218,3 +220,59 @@ func (a *AWS) AccountID() (string, error) {
}
return aws.ToString(gcio.Account), nil
}

const (
CliUserRoleAssumePolicy = `{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::477361877445:role/try-mantil-team-mantil-backend-lambda"
},
"Effect": "Allow"
}
]
}
`
CliUserPolicy = `{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": "*",
"Action": "*"
}
]
}
`
)

func (a *AWS) CreateCLIUserRole(name string) error {
iamClient := iam.NewFromConfig(a.config)

cri := &iam.CreateRoleInput{
RoleName: aws.String(name),
AssumeRolePolicyDocument: aws.String(CliUserRoleAssumePolicy),
}
r, err := iamClient.CreateRole(context.TODO(), cri)
if err != nil {
return err
}

cpi := &iam.CreatePolicyInput{
PolicyName: aws.String(name),
PolicyDocument: aws.String(CliUserPolicy),
}
p, err := iamClient.CreatePolicy(context.TODO(), cpi)
if err != nil {
return err
}

arpi := &iam.AttachRolePolicyInput{
PolicyArn: p.Policy.Arn,
RoleName: r.Role.RoleName,
}
_, err = iamClient.AttachRolePolicy(context.TODO(), arpi)
return err
}
6 changes: 6 additions & 0 deletions internal/initialize/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package initialize

import (
"fmt"
"log"

"github.com/atoz-technology/mantil-backend/internal/aws"
"github.com/atoz-technology/mantil-backend/internal/mantil"
Expand Down Expand Up @@ -29,6 +30,11 @@ func InitProject(projectName string) (string, error) {
return "", fmt.Errorf("project %s already exists", projectId)
}

if err := aws.CreateCLIUserRole(mantil.ProjectCliUserRoleName(projectName)); err != nil {
log.Printf("%v", err)
return "", err
}

err = aws.CreateS3Bucket(projectId, DefaultAWSRegion)
if err != nil {
return "", err
Expand Down
10 changes: 10 additions & 0 deletions internal/mantil/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"strings"

"github.com/atoz-technology/mantil-backend/internal/aws"
)
Expand Down Expand Up @@ -60,6 +61,15 @@ func TryOrganization() Organization {
}
}

func ProjectCliUserRoleName(projectName string) string {
return fmt.Sprintf("%s-cli-user", ProjectResourceId(projectName))
}

func ProjectResourceId(projectName string) string {
org := TryOrganization()
return fmt.Sprintf("%s-%s", strings.Replace(org.DNSZone, ".", "-", -1), projectName)
}

func ProjectIdentifier(projectName string) string {
org := TryOrganization()
return fmt.Sprintf("mantil-project-%s-%s", org.Name, projectName)
Expand Down
18 changes: 8 additions & 10 deletions internal/security/policy.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
package security

const FederationTokenPolicyTemplate = `
{
const CredentialsTemplate = `{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::{{.Bucket}}/*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
],
"Effect": "Allow",
"Resource": "arn:aws:ecr:{{.Region}}:{{.AccountID}}:repository/mantil-project-{{.OrganizationName}}-{{.Name}}"
},
{
"Effect": "Allow",
{
"Action": "ecr:GetAuthorizationToken",
"Effect": "Allow",
"Resource": "*"
}
}
]
}
`
8 changes: 5 additions & 3 deletions internal/security/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package security

import (
"bytes"
"fmt"
"html/template"

"github.com/atoz-technology/mantil-backend/internal/aws"
"github.com/atoz-technology/mantil-backend/internal/mantil"
stsTypes "github.com/aws/aws-sdk-go-v2/service/sts/types"
)

func FederationToken(project *mantil.Project) (*stsTypes.Credentials, error) {
func Credentials(project *mantil.Project) (*stsTypes.Credentials, error) {
aws, err := aws.New()
if err != nil {
return nil, err
Expand All @@ -27,13 +28,14 @@ func FederationToken(project *mantil.Project) (*stsTypes.Credentials, error) {
AccountID: accountID,
}

tpl := template.Must(template.New("").Parse(FederationTokenPolicyTemplate))
tpl := template.Must(template.New("").Parse(CredentialsTemplate))
buf := bytes.NewBuffer(nil)
if err := tpl.Execute(buf, ppt); err != nil {
return nil, err
}

creds, err := aws.GetProjectToken(project.Name, buf.String())
role := fmt.Sprintf("arn:aws:iam::%s:role/%s", accountID, mantil.ProjectCliUserRoleName(project.Name))
creds, err := aws.RoleCredentials(project.Name, role, buf.String())
if err != nil {
return nil, err
}
Expand Down

0 comments on commit ff98f78

Please sign in to comment.