SlideShare a Scribd company logo
Copyright © 2017 HashiCorp
Vault Plugin
Infrastructure
Nicolas Corrarello - Solutions Engineering
Lead International
HashiCorp
Nicolas Corrarello
Solutions Engineering Lead - International
International Man of Mystery, licensed to:
• Methodology
• Field Work
• Implementations
• Develop
• Document
• School runs
@nomadic_geek
@nomadic_geek
Vault rocks!!!
• Takes a sensible and programmatic
approach to security
• It’s Open Source
• It’s fast!
• It’s a “Security product” (As defined by
INFOSEC)
@nomadic_geek
There is something about Nomad….
What?!?!?!?
@nomadic_geek
Authentication Flow
LDAP Auth
Vault Token
Vault Token
Nomad Token
+ Nomad Token
@nomadic_geek
A great idea is not enough. Execute!
@nomadic_geek
Problems
A few biggies….
• Vault is written in Go, I’ve never written a single line of Go
• I knew how Vault works, but never payed attention to the
internals (See “I don’t know Go”)
• I’m in the US, jet lagged, and in a conference
@nomadic_geek
Advantages
1. I understand how both Vault and Nomad work
2. I know that the Consul backend does something pretty
similar
3. I’m motivated
4. I’m in the US, in a conference, next to a bunch of Vault
engineers I can ask questions to!
@nomadic_geek
What do I need to accomplish
Nomad Secret Backend
Access / TTL
Vault Logical Storage
config/access
config/lease
lease/*
role/*
Token Renew/Revoke
Role Create/Update/
Delete
Nomad Client
func Backend() *backend {
var b backend
b.Backend = &framework.Backend{
Paths: []*framework.Path{
pathConfigAccess(&b),
pathConfigLease(&b),
pathListRoles(&b),
pathRoles(&b),
pathCredsCreate(&b),
},
Secrets: []*framework.Secret{
secretToken(&b),
},
BackendType: logical.TypeLogical,
}
return &b
}
Backend Type:
TypeLogical,
TypeCredential
Standard Framework
Backend
FrontEnd Paths
Type of Secret
Standard Secret Framework
import (
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
func (b *backend) client(s logical.Storage) (*api.Client, error) {
conf, err := b.readConfigAccess(s)
if err != nil {
return nil, err
}
nomadConf := api.DefaultConfig()
nomadConf.Address = conf.Address
nomadConf.SecretID = conf.Token
client, err := api.NewClient(nomadConf)
if err != nil {
return nil, err
}
return client, nil
}
I need a client
Client Config
Error Handling
Error handling (lots)
Read Configuration
func pathConfigAccess(b *backend) *framework.Path {
return &framework.Path{
Pattern: "config/access",
Fields: map[string]*framework.FieldSchema{
"address": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Nomad server address",
},
"scheme": &framework.FieldSchema{
Type: framework.TypeString,
Description: "URI scheme for the Nomad address",
Default: "https",
},
"token": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Token for API calls",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.pathConfigAccessRead,
logical.UpdateOperation: b.pathConfigAccessWrite,
},
}
}
Need a function that return access configuration
Fields, lots of fields
Store it in API / Logical
Operations
func (b *backend) pathConfigAccessRead(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
conf, err := b.readConfigAccess(req.Storage)
if err != nil {
return nil, err
}
if conf == nil {
return nil, fmt.Errorf("nomad access configuration not found")
}
return &logical.Response{
Data: map[string]interface{}{
"address": conf.Address,
"scheme": conf.Scheme,
},
}, nil
}
func (b *backend) pathConfigAccessWrite(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
entry, err := logical.StorageEntryJSON("config/access", accessConfig{
Address: data.Get("address").(string),
Scheme: data.Get("scheme").(string),
Token: data.Get("token").(string),
})
if err != nil {
return nil, err
}
if err := req.Storage.Put(entry); err != nil {
return nil, err
}
return nil, nil
}
Define the function
Read Config
Handle Errors
Return Object
func secretToken(b *backend) *framework.Secret {
return &framework.Secret{
Type: SecretTokenType,
Fields: map[string]*framework.FieldSchema{
"token": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Request token",
},
},
Renew: b.secretTokenRenew,
Revoke: b.secretTokenRevoke,
}
}
func (b *backend) secretTokenRenew(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
lease, err := b.LeaseConfig(req.Storage)
if err != nil {
return nil, err
}
if lease == nil {
lease = &configLease{}
}
return framework.LeaseExtend(lease.TTL, lease.MaxTTL, b.System())(req, d)
}
func (b *backend) secretTokenRevoke(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
c, err := b.client(req.Storage)
if err != nil {
return nil, err
}
tokenRaw := req.Secret.InternalData["accessor_id"]
_, err = c.ACLTokens().Delete(tokenRaw.(string), nil)
if err != nil {
return nil, err
}
return nil, nil
}
Define the Secret Token function
Map Functions
Revoke Token
Renew Token
func (b *backend) pathRolesWrite(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
tokenType := d.Get("type").(string)
name := d.Get("name").(string)
global := d.Get("global").(bool)
policy := d.Get("policy").([]string)
switch tokenType {
case "client":
if len(policy) == 0 {
return logical.ErrorResponse(
"policy cannot be empty when using client tokens"), nil
}
case "management":
if len(policy) != 0 {
return logical.ErrorResponse(
"policy should be empty when using management tokens"), nil
}
default:
return logical.ErrorResponse(
"type must be "client" or "management""), nil
}
entry, err := logical.StorageEntryJSON("role/"+name, roleConfig{
Policy: policy,
TokenType: tokenType,
Global: global,
})
if err != nil {
return nil, err
}
if err := req.Storage.Put(entry); err != nil {
return nil, err
}
return nil, nil
}
Define the role creation function
Token Attributes
Store the role
Validate parameters
func pathCredsCreate(b *backend) *framework.Path {
return &framework.Path{
Pattern: "creds/" + framework.GenericNameRegex("name"),
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Name of the role",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.pathTokenRead,
},
}
}
Define the Credentials Creation Function
Map Functions
func (b *backend) pathTokenRead(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
role, err := b.Role(req.Storage, name)
if err != nil {
return nil, fmt.Errorf("error retrieving role: %s", err)
}
if role == nil {
return logical.ErrorResponse(fmt.Sprintf("Role '%s' not found", name)), nil
}
leaseConfig, err := b.LeaseConfig(req.Storage)
if err != nil {
return nil, err
}
if leaseConfig == nil {
leaseConfig = &configLease{}
}
c, err := b.client(req.Storage)
if err != nil {
return nil, err
}
tokenName := fmt.Sprintf("Vault %s %s %d", name, req.DisplayName, time.Now().UnixNano())
token, _, err := c.ACLTokens().Create(&api.ACLToken{
Name: tokenName,
Type: role.TokenType,
Policies: role.Policy,
Global: role.Global,
}, nil)
if err != nil {
return logical.ErrorResponse(err.Error()), nil
}
resp := b.Secret(SecretTokenType).Response(map[string]interface{}{
"secret_id": token.SecretID,
"accessor_id": token.AccessorID,
}, map[string]interface{}{
"accessor_id": token.AccessorID,
})
resp.Secret.TTL = leaseConfig.TTL
return resp, nil
}
Random string for token Name
Get the Role object (for the policy names)
Return accessor and token
But only store accessor
@nomadic_geek
Didn’t you say Plugin?
func main() {
apiClientMeta := &pluginutil.APIClientMeta{}
flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:])
tlsConfig := apiClientMeta.GetTLSConfig()
tlsProviderFunc := pluginutil.VaultPluginTLSProvider(tlsConfig)
if err := plugin.Serve(&plugin.ServeOpts{
BackendFactoryFunc: Factory,
TLSProviderFunc: tlsProviderFunc,
}); err != nil {
log.Fatal(err)
}
}
func Factory(c *logical.BackendConfig) (logical.Backend, error) {
b := Backend(c)
if err := b.Setup(c); err != nil {
return nil, err
}
return b, nil
}
type backend struct {
*framework.Backend
}
An independent process that communicates
With Vault using RPC
Using Mutual TLS automatically generated
Create Factory
Define Backend
@nomadic_geek
Lessons learned
• Go, err := ‘awesome’, nil
• So many things in Vault were so seamless that really looked like magic.
• The best kept secret is the one you don’t know about.
• Attach all your functions to the Backend of your plugin (Client, Token, Role).
• If I have a pence for each if err == nil … (Seriously, maybe 30% of my code is error handling).
• The other 60% of my code, is just mapping interfaces existing in Vault.
• The remaining 10%, logic that I wrote.
• GoDoc is your friend.
• You can actually write plugins in different languages (see gRPC)
• Document your stuff (https://github.com/hashicorp/vault/tree/f-nomad/website/source/docs/secrets/
nomad).
@nomadic_geek
Reference
• Full Code in the f-nomad branch (soon to be master): https://github.com/hashicorp/vault/tree/f-
nomad/builtin/logical/nomad
• Seth Vargo did an awesome post on this (with examples) that cover Auth Plugins:
• https://www.hashicorp.com/blog/building-a-vault-secure-plugin
• https://github.com/sethvargo/vault-auth-slack
• A couple of recommended HashiConf talks:
• https://www.youtube.com/watch?v=bCNSvUrK_BA - Deep dive on Vault AWS Auth backend
• https://www.youtube.com/watch?v=rd0xyT8xMqg - Authenticating to Vault with Google Platform
COME JOIN US
HashiCorp.com/jobs
Thank you.
hello@hashicorp.comwww.hashicorp.com

More Related Content

What's hot

Issuing temporary credentials for my sql using hashicorp vault
Issuing temporary credentials for my sql using hashicorp vaultIssuing temporary credentials for my sql using hashicorp vault
Issuing temporary credentials for my sql using hashicorp vault
OlinData
 
Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault
Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault
Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault
Outlyer
 
Vault 101
Vault 101Vault 101
Vault 101
Hazzim Anaya
 
Vault
VaultVault
Vault
dawnlua
 
Dynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency PlanningDynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency Planning
Sean Chittenden
 
A tale of application development
A tale of application developmentA tale of application development
A tale of application development
Nicolas Corrarello
 
Vault
VaultVault
Vault 1.1: Secret Caching with Vault Agent and Other New Features
Vault 1.1: Secret Caching with Vault Agent and Other New FeaturesVault 1.1: Secret Caching with Vault Agent and Other New Features
Vault 1.1: Secret Caching with Vault Agent and Other New Features
Mitchell Pronschinske
 
Keeping a Secret with HashiCorp Vault
Keeping a Secret with HashiCorp VaultKeeping a Secret with HashiCorp Vault
Keeping a Secret with HashiCorp Vault
Mitchell Pronschinske
 
Securing Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp VaultSecuring Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp Vault
Bram Vogelaar
 
Nomad + Flatcar: a harmonious marriage of lightweights
Nomad + Flatcar: a harmonious marriage of lightweightsNomad + Flatcar: a harmonious marriage of lightweights
Nomad + Flatcar: a harmonious marriage of lightweights
Iago López Galeiras
 
HTTP For the Good or the Bad
HTTP For the Good or the BadHTTP For the Good or the Bad
HTTP For the Good or the Bad
Xavier Mertens
 
A Case Study in Attacking KeePass
A Case Study in Attacking KeePassA Case Study in Attacking KeePass
A Case Study in Attacking KeePass
Will Schroeder
 
Managing Your Security Logs with Elasticsearch
Managing Your Security Logs with ElasticsearchManaging Your Security Logs with Elasticsearch
Managing Your Security Logs with Elasticsearch
Vic Hargrave
 
Exploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osqueryExploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osquery
Zachary Wasserman
 
AWS Cost Control: Cloud Custodian
AWS Cost Control: Cloud CustodianAWS Cost Control: Cloud Custodian
AWS Cost Control: Cloud Custodian
OlinData
 
Nodejsvault austin2019
Nodejsvault austin2019Nodejsvault austin2019
Nodejsvault austin2019
Taswar Bhatti
 
Web前端性能优化 2014
Web前端性能优化 2014Web前端性能优化 2014
Web前端性能优化 2014
Yubei Li
 
Pycon - Python for ethical hackers
Pycon - Python for ethical hackers Pycon - Python for ethical hackers
Pycon - Python for ethical hackers
Mohammad Reza Kamalifard
 
Types of ssl commands and keytool
Types of ssl commands and keytoolTypes of ssl commands and keytool
Types of ssl commands and keytool
CheapSSLsecurity
 

What's hot (20)

Issuing temporary credentials for my sql using hashicorp vault
Issuing temporary credentials for my sql using hashicorp vaultIssuing temporary credentials for my sql using hashicorp vault
Issuing temporary credentials for my sql using hashicorp vault
 
Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault
Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault
Neil Saunders (Beamly) - Securing your AWS Infrastructure with Hashicorp Vault
 
Vault 101
Vault 101Vault 101
Vault 101
 
Vault
VaultVault
Vault
 
Dynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency PlanningDynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency Planning
 
A tale of application development
A tale of application developmentA tale of application development
A tale of application development
 
Vault
VaultVault
Vault
 
Vault 1.1: Secret Caching with Vault Agent and Other New Features
Vault 1.1: Secret Caching with Vault Agent and Other New FeaturesVault 1.1: Secret Caching with Vault Agent and Other New Features
Vault 1.1: Secret Caching with Vault Agent and Other New Features
 
Keeping a Secret with HashiCorp Vault
Keeping a Secret with HashiCorp VaultKeeping a Secret with HashiCorp Vault
Keeping a Secret with HashiCorp Vault
 
Securing Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp VaultSecuring Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp Vault
 
Nomad + Flatcar: a harmonious marriage of lightweights
Nomad + Flatcar: a harmonious marriage of lightweightsNomad + Flatcar: a harmonious marriage of lightweights
Nomad + Flatcar: a harmonious marriage of lightweights
 
HTTP For the Good or the Bad
HTTP For the Good or the BadHTTP For the Good or the Bad
HTTP For the Good or the Bad
 
A Case Study in Attacking KeePass
A Case Study in Attacking KeePassA Case Study in Attacking KeePass
A Case Study in Attacking KeePass
 
Managing Your Security Logs with Elasticsearch
Managing Your Security Logs with ElasticsearchManaging Your Security Logs with Elasticsearch
Managing Your Security Logs with Elasticsearch
 
Exploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osqueryExploring, understanding and monitoring macOS activity with osquery
Exploring, understanding and monitoring macOS activity with osquery
 
AWS Cost Control: Cloud Custodian
AWS Cost Control: Cloud CustodianAWS Cost Control: Cloud Custodian
AWS Cost Control: Cloud Custodian
 
Nodejsvault austin2019
Nodejsvault austin2019Nodejsvault austin2019
Nodejsvault austin2019
 
Web前端性能优化 2014
Web前端性能优化 2014Web前端性能优化 2014
Web前端性能优化 2014
 
Pycon - Python for ethical hackers
Pycon - Python for ethical hackers Pycon - Python for ethical hackers
Pycon - Python for ethical hackers
 
Types of ssl commands and keytool
Types of ssl commands and keytoolTypes of ssl commands and keytool
Types of ssl commands and keytool
 

Similar to HashiCorp Vault Plugin Infrastructure

Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...
Docker, Inc.
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
Jorge Lopez-Malla
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responses
darrelmiller71
 
Web2.0 with jQuery in English
Web2.0 with jQuery in EnglishWeb2.0 with jQuery in English
Web2.0 with jQuery in English
Lau Bech Lauritzen
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
Rowan Merewood
 
Azure F#unctions
Azure F#unctionsAzure F#unctions
Azure F#unctions
☁️ Mikhail Shilkov
 
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
BradNeuberg
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
postrational
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
GeeksLab Odessa
 
外部環境への依存をテストする
外部環境への依存をテストする外部環境への依存をテストする
外部環境への依存をテストする
Shunsuke Maeda
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive Apps
Jorge Ortiz
 
Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0
Frost
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
Porting legacy apps to Griffon
Porting legacy apps to GriffonPorting legacy apps to Griffon
Porting legacy apps to Griffon
James Williams
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
Eberhard Wolff
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
JAX London
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
Codemotion
 
Automated malware analysis
Automated malware analysisAutomated malware analysis
Automated malware analysis
Ibrahim Baliç
 

Similar to HashiCorp Vault Plugin Infrastructure (20)

Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responses
 
Web2.0 with jQuery in English
Web2.0 with jQuery in EnglishWeb2.0 with jQuery in English
Web2.0 with jQuery in English
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Azure F#unctions
Azure F#unctionsAzure F#unctions
Azure F#unctions
 
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
Beyond Cookies, Persistent Storage For Web Applications Web Directions North ...
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
外部環境への依存をテストする
外部環境への依存をテストする外部環境への依存をテストする
外部環境への依存をテストする
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive Apps
 
Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Porting legacy apps to Griffon
Porting legacy apps to GriffonPorting legacy apps to Griffon
Porting legacy apps to Griffon
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 
Automated malware analysis
Automated malware analysisAutomated malware analysis
Automated malware analysis
 
Dlr
DlrDlr
Dlr
 

Recently uploaded

Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
Sharepoint Designs
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
Jelle | Nordend
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Anthony Dahanne
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
IES VE
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Hivelance Technology
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 

Recently uploaded (20)

Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 

HashiCorp Vault Plugin Infrastructure

  • 1. Copyright © 2017 HashiCorp Vault Plugin Infrastructure Nicolas Corrarello - Solutions Engineering Lead International HashiCorp
  • 2. Nicolas Corrarello Solutions Engineering Lead - International International Man of Mystery, licensed to: • Methodology • Field Work • Implementations • Develop • Document • School runs @nomadic_geek
  • 3. @nomadic_geek Vault rocks!!! • Takes a sensible and programmatic approach to security • It’s Open Source • It’s fast! • It’s a “Security product” (As defined by INFOSEC)
  • 6. @nomadic_geek Authentication Flow LDAP Auth Vault Token Vault Token Nomad Token + Nomad Token
  • 7. @nomadic_geek A great idea is not enough. Execute!
  • 8. @nomadic_geek Problems A few biggies…. • Vault is written in Go, I’ve never written a single line of Go • I knew how Vault works, but never payed attention to the internals (See “I don’t know Go”) • I’m in the US, jet lagged, and in a conference
  • 9. @nomadic_geek Advantages 1. I understand how both Vault and Nomad work 2. I know that the Consul backend does something pretty similar 3. I’m motivated 4. I’m in the US, in a conference, next to a bunch of Vault engineers I can ask questions to!
  • 10. @nomadic_geek What do I need to accomplish Nomad Secret Backend Access / TTL Vault Logical Storage config/access config/lease lease/* role/* Token Renew/Revoke Role Create/Update/ Delete Nomad Client
  • 11. func Backend() *backend { var b backend b.Backend = &framework.Backend{ Paths: []*framework.Path{ pathConfigAccess(&b), pathConfigLease(&b), pathListRoles(&b), pathRoles(&b), pathCredsCreate(&b), }, Secrets: []*framework.Secret{ secretToken(&b), }, BackendType: logical.TypeLogical, } return &b } Backend Type: TypeLogical, TypeCredential Standard Framework Backend FrontEnd Paths Type of Secret Standard Secret Framework
  • 12. import ( "github.com/hashicorp/nomad/api" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) func (b *backend) client(s logical.Storage) (*api.Client, error) { conf, err := b.readConfigAccess(s) if err != nil { return nil, err } nomadConf := api.DefaultConfig() nomadConf.Address = conf.Address nomadConf.SecretID = conf.Token client, err := api.NewClient(nomadConf) if err != nil { return nil, err } return client, nil } I need a client Client Config Error Handling Error handling (lots) Read Configuration
  • 13. func pathConfigAccess(b *backend) *framework.Path { return &framework.Path{ Pattern: "config/access", Fields: map[string]*framework.FieldSchema{ "address": &framework.FieldSchema{ Type: framework.TypeString, Description: "Nomad server address", }, "scheme": &framework.FieldSchema{ Type: framework.TypeString, Description: "URI scheme for the Nomad address", Default: "https", }, "token": &framework.FieldSchema{ Type: framework.TypeString, Description: "Token for API calls", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ logical.ReadOperation: b.pathConfigAccessRead, logical.UpdateOperation: b.pathConfigAccessWrite, }, } } Need a function that return access configuration Fields, lots of fields Store it in API / Logical Operations
  • 14. func (b *backend) pathConfigAccessRead( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { conf, err := b.readConfigAccess(req.Storage) if err != nil { return nil, err } if conf == nil { return nil, fmt.Errorf("nomad access configuration not found") } return &logical.Response{ Data: map[string]interface{}{ "address": conf.Address, "scheme": conf.Scheme, }, }, nil } func (b *backend) pathConfigAccessWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { entry, err := logical.StorageEntryJSON("config/access", accessConfig{ Address: data.Get("address").(string), Scheme: data.Get("scheme").(string), Token: data.Get("token").(string), }) if err != nil { return nil, err } if err := req.Storage.Put(entry); err != nil { return nil, err } return nil, nil } Define the function Read Config Handle Errors Return Object
  • 15. func secretToken(b *backend) *framework.Secret { return &framework.Secret{ Type: SecretTokenType, Fields: map[string]*framework.FieldSchema{ "token": &framework.FieldSchema{ Type: framework.TypeString, Description: "Request token", }, }, Renew: b.secretTokenRenew, Revoke: b.secretTokenRevoke, } } func (b *backend) secretTokenRenew( req *logical.Request, d *framework.FieldData) (*logical.Response, error) { lease, err := b.LeaseConfig(req.Storage) if err != nil { return nil, err } if lease == nil { lease = &configLease{} } return framework.LeaseExtend(lease.TTL, lease.MaxTTL, b.System())(req, d) } func (b *backend) secretTokenRevoke( req *logical.Request, d *framework.FieldData) (*logical.Response, error) { c, err := b.client(req.Storage) if err != nil { return nil, err } tokenRaw := req.Secret.InternalData["accessor_id"] _, err = c.ACLTokens().Delete(tokenRaw.(string), nil) if err != nil { return nil, err } return nil, nil } Define the Secret Token function Map Functions Revoke Token Renew Token
  • 16. func (b *backend) pathRolesWrite( req *logical.Request, d *framework.FieldData) (*logical.Response, error) { tokenType := d.Get("type").(string) name := d.Get("name").(string) global := d.Get("global").(bool) policy := d.Get("policy").([]string) switch tokenType { case "client": if len(policy) == 0 { return logical.ErrorResponse( "policy cannot be empty when using client tokens"), nil } case "management": if len(policy) != 0 { return logical.ErrorResponse( "policy should be empty when using management tokens"), nil } default: return logical.ErrorResponse( "type must be "client" or "management""), nil } entry, err := logical.StorageEntryJSON("role/"+name, roleConfig{ Policy: policy, TokenType: tokenType, Global: global, }) if err != nil { return nil, err } if err := req.Storage.Put(entry); err != nil { return nil, err } return nil, nil } Define the role creation function Token Attributes Store the role Validate parameters
  • 17. func pathCredsCreate(b *backend) *framework.Path { return &framework.Path{ Pattern: "creds/" + framework.GenericNameRegex("name"), Fields: map[string]*framework.FieldSchema{ "name": &framework.FieldSchema{ Type: framework.TypeString, Description: "Name of the role", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ logical.ReadOperation: b.pathTokenRead, }, } } Define the Credentials Creation Function Map Functions
  • 18. func (b *backend) pathTokenRead( req *logical.Request, d *framework.FieldData) (*logical.Response, error) { name := d.Get("name").(string) role, err := b.Role(req.Storage, name) if err != nil { return nil, fmt.Errorf("error retrieving role: %s", err) } if role == nil { return logical.ErrorResponse(fmt.Sprintf("Role '%s' not found", name)), nil } leaseConfig, err := b.LeaseConfig(req.Storage) if err != nil { return nil, err } if leaseConfig == nil { leaseConfig = &configLease{} } c, err := b.client(req.Storage) if err != nil { return nil, err } tokenName := fmt.Sprintf("Vault %s %s %d", name, req.DisplayName, time.Now().UnixNano()) token, _, err := c.ACLTokens().Create(&api.ACLToken{ Name: tokenName, Type: role.TokenType, Policies: role.Policy, Global: role.Global, }, nil) if err != nil { return logical.ErrorResponse(err.Error()), nil } resp := b.Secret(SecretTokenType).Response(map[string]interface{}{ "secret_id": token.SecretID, "accessor_id": token.AccessorID, }, map[string]interface{}{ "accessor_id": token.AccessorID, }) resp.Secret.TTL = leaseConfig.TTL return resp, nil } Random string for token Name Get the Role object (for the policy names) Return accessor and token But only store accessor
  • 19.
  • 21. func main() { apiClientMeta := &pluginutil.APIClientMeta{} flags := apiClientMeta.FlagSet() flags.Parse(os.Args[1:]) tlsConfig := apiClientMeta.GetTLSConfig() tlsProviderFunc := pluginutil.VaultPluginTLSProvider(tlsConfig) if err := plugin.Serve(&plugin.ServeOpts{ BackendFactoryFunc: Factory, TLSProviderFunc: tlsProviderFunc, }); err != nil { log.Fatal(err) } } func Factory(c *logical.BackendConfig) (logical.Backend, error) { b := Backend(c) if err := b.Setup(c); err != nil { return nil, err } return b, nil } type backend struct { *framework.Backend } An independent process that communicates With Vault using RPC Using Mutual TLS automatically generated Create Factory Define Backend
  • 22. @nomadic_geek Lessons learned • Go, err := ‘awesome’, nil • So many things in Vault were so seamless that really looked like magic. • The best kept secret is the one you don’t know about. • Attach all your functions to the Backend of your plugin (Client, Token, Role). • If I have a pence for each if err == nil … (Seriously, maybe 30% of my code is error handling). • The other 60% of my code, is just mapping interfaces existing in Vault. • The remaining 10%, logic that I wrote. • GoDoc is your friend. • You can actually write plugins in different languages (see gRPC) • Document your stuff (https://github.com/hashicorp/vault/tree/f-nomad/website/source/docs/secrets/ nomad).
  • 23. @nomadic_geek Reference • Full Code in the f-nomad branch (soon to be master): https://github.com/hashicorp/vault/tree/f- nomad/builtin/logical/nomad • Seth Vargo did an awesome post on this (with examples) that cover Auth Plugins: • https://www.hashicorp.com/blog/building-a-vault-secure-plugin • https://github.com/sethvargo/vault-auth-slack • A couple of recommended HashiConf talks: • https://www.youtube.com/watch?v=bCNSvUrK_BA - Deep dive on Vault AWS Auth backend • https://www.youtube.com/watch?v=rd0xyT8xMqg - Authenticating to Vault with Google Platform