SlideShare uma empresa Scribd logo
1 de 25
Baixar para ler offline
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

Mais conteúdo relacionado

Mais procurados

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 vaultOlinData
 
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
 
Dynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency PlanningDynamic Database Credentials: Security Contingency Planning
Dynamic Database Credentials: Security Contingency PlanningSean Chittenden
 
A tale of application development
A tale of application developmentA tale of application development
A tale of application developmentNicolas Corrarello
 
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 FeaturesMitchell Pronschinske
 
Keeping a Secret with HashiCorp Vault
Keeping a Secret with HashiCorp VaultKeeping a Secret with HashiCorp Vault
Keeping a Secret with HashiCorp VaultMitchell Pronschinske
 
Securing Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp VaultSecuring Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp VaultBram 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 lightweightsIago 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 BadXavier Mertens
 
A Case Study in Attacking KeePass
A Case Study in Attacking KeePassA Case Study in Attacking KeePass
A Case Study in Attacking KeePassWill Schroeder
 
Managing Your Security Logs with Elasticsearch
Managing Your Security Logs with ElasticsearchManaging Your Security Logs with Elasticsearch
Managing Your Security Logs with ElasticsearchVic 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 osqueryZachary Wasserman
 
AWS Cost Control: Cloud Custodian
AWS Cost Control: Cloud CustodianAWS Cost Control: Cloud Custodian
AWS Cost Control: Cloud CustodianOlinData
 
Nodejsvault austin2019
Nodejsvault austin2019Nodejsvault austin2019
Nodejsvault austin2019Taswar Bhatti
 
Web前端性能优化 2014
Web前端性能优化 2014Web前端性能优化 2014
Web前端性能优化 2014Yubei Li
 
Types of ssl commands and keytool
Types of ssl commands and keytoolTypes of ssl commands and keytool
Types of ssl commands and keytoolCheapSSLsecurity
 

Mais procurados (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
 

Semelhante a 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 eastJorge Lopez-Malla
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responsesdarrelmiller71
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
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 architecturepostrational
 
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 AppsJorge 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.0Frost
 
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 GriffonJames Williams
 
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 WolffJAX 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 - WarburtonCodemotion
 
Automated malware analysis
Automated malware analysisAutomated malware analysis
Automated malware analysisIbrahim Baliç
 

Semelhante a 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
 

Último

%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile EnvironmentVictorSzoltysek
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 

Último (20)

%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 

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