finto

package module
v0.0.0-...-d54f53b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2022 License: MIT Imports: 9 Imported by: 0

README

finto

Build Status

finto (-a) /'finto (-a)/ agg 1 posticcio; artificiàle

Overview

finto is a web server that emulates EC2 instance profile roles on a workstation through STS's assume role function. It was born as an experiment to ease local interaction with AWS services in a deeply-federated, role-based environment. finto ships with a basic API for moving between roles, and handles credentials caching and expiration.

Installation

At its simplest:

go get github.com/threadwaste/finto/cmd/finto

Usage

Usage of finto:
  -addr="169.254.169.254": bind to addr
  -config="/home/demo/.fintorc": location of config file
  -log="": log http to file
  -port=16925: listen on port

While running, finto provides credentials to EC2 instance profile providers. This provider is last in the default provider chain of each SDK. For more information, refer to the official documentation on EC2 instance profile roles and the standardized credentials interface.

Below is sample output of finto serving credentials to the AWS CLI:

$ aws s3 ls --debug
<truncated>
2016-01-03 11:52:01,895 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: env
2016-01-03 11:52:01,895 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: assume-role
2016-01-03 11:52:01,895 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: shared-credentials-file
2016-01-03 11:52:01,896 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: config-file
2016-01-03 11:52:01,896 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: ec2-credentials-file
2016-01-03 11:52:01,896 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: boto-config
2016-01-03 11:52:01,897 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: iam-role
2016-01-03 11:52:01,902 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - INFO - Starting new HTTP connection (1): 169.254.169.254
2016-01-03 11:52:01,904 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - DEBUG - "GET /latest/meta-data/iam/security-credentials/ HTTP/1.1" 200 5
2016-01-03 11:52:02,259 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - DEBUG - "GET /latest/meta-data/iam/security-credentials/example HTTP/1.1" 200 635
2016-01-03 11:52:02,261 - MainThread - botocore.credentials - INFO - Found credentials from IAM Role: example
<truncated>
2016-01-03 11:52:03,282 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.ListBuckets: calling handler <awscli.errorhandler.ErrorHandler object at 0x10483fc90>
2016-01-03 11:52:03,282 - MainThread - awscli.errorhandler - DEBUG - HTTP Response Code: 200

finto also includes an API for bouncing between available roles. Helper functions for bash and fish shells are available.

$ curl 169.254.169.254/roles
{"roles":["example","example2"]}
$ curl 169.254.169.254/roles/example
{"arn":"arn:aws:iam::123456789012:role/example","session_name":"finto-example"}
$ curl 169.254.169.254/roles/example/credentials
{
  "AccessKeyId": "<redacted>",
  "Code": "Success",
  "Expiration": "2016-01-03T19:40:30Z",
  "LastUpdated": "2015-07-07T23:06:33Z",
  "SecretAccessKey": "<redacted>",
  "Token": "<redacted>",
  "Type": "AWS-HMAC"
}
$ curl 169.254.169.254/latest/meta-data/iam/security-credentials/
example
$ curl -XPUT -d'{"alias":"example2"}' 169.254.169.254/roles
{"active_role":"example2"}
$ curl 169.254.169.254/latest/meta-data/iam/security-credentials/
example2

Configuration

finto uses a JSON configuration file to setup its credentials and the roles it will serve. It currently uses a shared credentials provider only. Exluding the credentials file or profile will use the defaults "~/.aws/credentials" and "default," respectively.

{
  "credentials": {
    "file": "/home/demo/.finto/credentials",
    "profile": "identity"
  },
  "roles": {
    "example": "arn:aws:iam::123456789012:role/example",
    "example2": "arn:aws:iam::123456789012:role/example2"
  }
  "default_role": "example",
}

Running

There are essentially two basic requirements for running finto:

  1. Routing the EC2 meta-data endpoint
  2. Using (or chaining to) the EC2 instance profile provider

The first can be achieved in several ways: interface aliasing, network redirection, virtual machines, and so on. The wiki contains a couple of basic examples.

The second is client-dependent. In the case of clients like the AWS CLI, the user must clear a path to the EC2 instance profile provider. Multiple shared credentials profiles can still be configured, and accessed with e.g. the --profile option or AWS_DEFAULT_PROFILE environment variable.

Development

After cloning the repository, running make will fetch and build dependencies; run tests; and install the binary. During development, make testall requires the following environment variables for its integration tests:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • FINTO_VALID_ARN - an IAM role ARN that can be assumed
  • FINTO_INVALID_ARN - a false IAM role ARN that will fail

The target test can be used to skip the integration tests, and avoid this setup.

Documentation

Index

Constants

View Source
const Version = "0.1.0"

Variables

This section is empty.

Functions

func FintoRouter

func FintoRouter(fc *fintoContext) *mux.Router

func InitFintoContext

func InitFintoContext(rs *RoleSet, defrole string) (fintoContext, error)

Types

type AssumeRoleClient

type AssumeRoleClient interface {
	AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
}

AssumeRoleClient is a basic interface that wraps role assumption.

AssumeRole takes the input of a role ARN and session name, and returns a set of credentials including: an access key ID, a secret access key, a session token, and their expiration.

https://godoc.org/github.com/aws/aws-sdk-go/service/sts#AssumeRoleInput https://godoc.org/github.com/aws/aws-sdk-go/service/sts#AssumeRoleOutput

type Credentials

type Credentials struct {
	AccessKeyId     string
	Expiration      time.Time
	SecretAccessKey string
	SessionToken    string
}

Credentials represents a set of temporary credentials and their expiration.

func (*Credentials) IsExpired

func (c *Credentials) IsExpired() bool

func (*Credentials) SetCredentials

func (c *Credentials) SetCredentials(id, key, token string)

func (*Credentials) SetExpiration

func (c *Credentials) SetExpiration(t time.Time, offset time.Duration)

Sets expiration. Accepts an offset to allow for early expiration. This helps avoid returning credentials that expire "in flight."

type Role

type Role struct {
	// contains filtered or unexported fields
}

Implements a role, the retrieval of its credentials, and management of their expiration.

func NewRole

func NewRole(a, s string, c AssumeRoleClient) *Role

func (*Role) Arn

func (r *Role) Arn() string

func (*Role) Credentials

func (r *Role) Credentials() (Credentials, error)

Returns the role's credentials. If expired, credentials are refreshed through the client.

func (*Role) IsExpired

func (r *Role) IsExpired() bool

Returns whether the role's current credentials are expired.

func (*Role) SessionName

func (r *Role) SessionName() string

type RoleSet

type RoleSet struct {
	// contains filtered or unexported fields
}

A collection of aliased roles.

func NewRoleSet

func NewRoleSet(c AssumeRoleClient) *RoleSet

func (*RoleSet) Role

func (rs *RoleSet) Role(alias string) (*Role, error)

func (*RoleSet) Roles

func (rs *RoleSet) Roles() (roles []string)

func (*RoleSet) SetRole

func (rs *RoleSet) SetRole(alias, arn string)

Set an alias's role configuration.

type Route

type Route struct {
	Handler fintoHandlerFunc
	Method  string
	Name    string
	Pattern string
}

type Routes

type Routes []Route

type VarsHandlerFunc

type VarsHandlerFunc func(http.ResponseWriter, *http.Request, map[string]string)

VarsHandlerFunc accepts mux route variables as an argument.

func (VarsHandlerFunc) ServeHTTP

func (f VarsHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL