SlideShare a Scribd company logo
1 of 50
Or,“why do we keep baking secrets into our artifacts?”
Symfony finally
swiped right on
envvars
Or,“why do we keep baking secrets into our artifacts?”
Symfony finally
swiped right on
envvars
just a collection of
cool gifs
Hi, I’m Sam
● Long time listener, first time caller.
● Co-organiser of this group.
● Using Symfony since 2.0 beta.
● Day job - ops @ REA.
● Docker & build automation fanboy.
● Have committed terrible atrocities with VCS and
build systems in the past.
Symfony is
not your grandma’s
framework
unique as a web framework
Most frameworks
re-read config at
boot.
(Every. page. load.)
$ bin/elasticsearch
...waits 30 seconds...
$ curl localhost:9200
[timeout]
...waits 30 more seconds...
$ curl localhost:9200
[timeout]
Symfony compiles
the DI container to
PHP, including all
config values.
Let’s talk about
secrets, baby.
What is a secret?
● Database credentials
● SMTP creds
● Payment gateway keys
● AWS credentials
● SMS tokens
● EDM service API keys
Beyond 11 herbs and spices
The modern app has so many..
● S3 bucket names
● SSH or deploy keys
● JWT keys or certificates
● Service n’s API key
● Other internal system hostnames
But really, an application secret is anything you wouldn’t
put directly in the HTML markup itself.
Here’s why we get a bad
rep as php developers[1][2]
…
1: I’ve seen all of these examples used
2: you probably have, too
<?php
class Config {
const LIVE_DATABASE_STRING = 'mysql://root:root@localhost:3306/pro
const TEST_DATABASE_STRING = 'mysql://root:root@localhost:3306/tes
public static function getDatabaseString() {
// @TODO add magic to determine environment
return self::LIVE_DATABASE_STRING;
}
// ...etc
The know it all “pattern”
The build it & they’ll come “pattern”
1. put your prod & test values in a config file
2. run “make config” or some other magic build script
3. generate PHP from template:
<?php
class Config {
const DATABASE_STRING = '{{ database_string }}';
public static function getDatabaseString() {
return self::DATABASE_STRING;
dropping a prod
database on a
misconfigured
test site. - my biggest professional fuck up.
probably?
config_dev.yml:
doctrine:
dbal:
url: 'mysql://root:root@localhost:3306/dev'
The config.yml is the new Config
class…. “pattern”
config_prod.yml:
doctrine:
dbal:
url: 'mysql://root:fk!ash#@localhost:3306/pr
Into today*...
* as is common in many
Symfony projects
Note: This is the best of the bad, but Symfony makes it insecure & hard to
update.
1. define your config keys in a file called parameters.yml.dist, set sane defaults
2. store the actual configuration on S3 / build servers / CI / somewhere else
3. at build-time, copy the file in & build the container (cache-warm)
The Fabien told me to “pattern”
OK. What’s
wrong with this?
How secure is your CI?
Who has access to wherever the
parameter values are stored?
OK. What’s
wrong with this?
Rolling the keys means re-deploying
the application.
OK. What’s
wrong with this?
Secrets are written into the
compiled Container class file.
Try it yourself:
$ grep “database.host”
var/cache/prod/*.php
OK. What’s
wrong with this?
Creating new deployments is hard.
OK. What’s
wrong with this?
Production artifact differs to test.
OK, so what’s the answer?
Introducing environment variables
✅ Easy to set up in the app
✅ Functions just like another parameter
✅ Not compiled into the container
✅ Like other parameters, allows default values to be set
✅ Updating values is as simple as updating wherever it’s
stored & reload PHP
Introducing environment variables
❌ Can’t access outside services - i.e. controllers etc -
may require app refactoring
❌ Can be difficult to implement if you run your app
outside of Docker
❌ Some libraries don’t quite support envvars yet
(there’s a workaround though!)
Porting an existing
app is easy.
parameters:
env(DATABASE_URL): mysql://root:root@db:3306/symfony?charset=
env(MAILER_HOST): smtp.sparkpostmail.com
env(MAILER_PORT): 587
env(MAILER_USER): SMTP_Injection
env(MAILER_PASS):
env(SECRET): ThisTokenIsNotSoSecretChangeIt
short_link_host: %env(SHORT_LINK_HOST)%
env(SHORT_LINK_HOST): fallback.local
Default values, get overridden if provided in the
env
How I dealt with libraries that don’t support env vars or
values needed in controllers
Note the structure
around the name
doctrine:
dbal:
url: '%env(DATABASE_URL)%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
swiftmailer:
transport: "smtp"
host: "%env(MAILER_HOST)%"
port: "%env(MAILER_PORT)%"
username: "%env(MAILER_USER)%"
password: "%env(MAILER_PASS)%"
spool: { type: "memory" }
How they’re used - in configuration YAML files...
services:
amazon_s3:
class: AwsS3S3Client
arguments:
- credentials:
key: "%env(AWS_ACCESS_KEY_ID)%"
secret: "%env(AWS_ACCESS_SECRET_KEY)%"
region: "%env(AWS_REGION)%"
version: "2006-03-01"
How they’re used - in service configuration files...
While you’re porting
● Consider what values actually change between
deployment environments
● Anything that doesn’t change, should go into
config.yml, config_dev.yml or
config_prod.yml (a la current standard edition
practice).
● Anything that changes is a good candidate to live in
the environment.
Any gotchas?
● Need to defer making decisions on anything that
changes per-deployment until later.
i.e. any decisions made in a container extension.
● Dynamic parameters don’t solve this
%param% => %env(PARAM)%
● If it’s your bundle/extension, you can use factory
services to work around this.
The Dotenv component in 3.3
● Symfony flex uses it out of the box!
● A small class that is added in your app/app_dev.php
and console scripts
● Provides env-var like support in places you can’t
easily set variables (dev!)
● In Flex, it replaces the parameters.yml paradigm
● Relatively easy to back-port into the full-stack
framework
Or…
You can use docker
in development!
It’s not (all) about
security.
Environment vars are not perfect
● Does not solve security for anyone with access to the machine.
● Can still be accessed from outside your app - i.e. anything in
shell_exec() calls.
● The PHP user or someone on CLI can expose to another program.
● Any insecure libraries in your app can access it, too.
● Can unintentionally turn up in logs, the Symfony profiler, etc.
● The plain-text values are probably still stored somewhere.
How do I make it better?
● Current PR: github/symfony/symfony#23901 (due 3.4) adds features to
support docker/kubernetes secrets & make it extendable.
● Once it’s available to us, it might be like this…
○ on AWS? KMS-encrypted envvars or SSM Param. Store.
○ Not AWS? G-Cloud KMS, or other open-source, e.g. Hashicorp
Vault, Pinterest Knox, Lyft Confidant.
● In the meantime: do you host on AWS? Use KMS-encrypted environment
variables or fetch from SSM Param. Store at container boot.
● Any of these principles a surprise? Read about 12-factor apps
● Segment have a great write-up on managing secrets on AWS on their
blog.
● KMS-ed envvars (enc. strings): REA’s Shush is a tiny go library to help.
● SSM param. store (central management): Segment’s Chamber can help.
● Taking inspo from k8s, Docker swarm mode now has secrets built-in.
● Not using Docker? Can be quite complicated to set env across multiple
users + daemons. Apache, and CLI users share a syntax, PHP-FPM is
different.
● Example of porting a Symfony app to Docker - for the adventurous.
Further reading & tools
thank you.
stalky stalk: @sammyjarrett or linkedin.com/in/samjarrett
more detail and these slides
published at samjarrett.com.au/swipe-right

More Related Content

What's hot

Go Faster with Ansible (AWS meetup)
Go Faster with Ansible (AWS meetup)Go Faster with Ansible (AWS meetup)
Go Faster with Ansible (AWS meetup)Richard Donkin
 
Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)Timothy Appnel
 
Ansible 2.0 - How to use Ansible to automate your applications in AWS.
Ansible 2.0 - How to use Ansible to automate your applications in AWS.Ansible 2.0 - How to use Ansible to automate your applications in AWS.
Ansible 2.0 - How to use Ansible to automate your applications in AWS.Idan Tohami
 
快快樂樂用Homestead
快快樂樂用Homestead快快樂樂用Homestead
快快樂樂用HomesteadChen Cheng-Wei
 
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоIaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоSigma Software
 
Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Michele Orselli
 
Introduction to vSphere APIs Using pyVmomi
Introduction to vSphere APIs Using pyVmomiIntroduction to vSphere APIs Using pyVmomi
Introduction to vSphere APIs Using pyVmomiMichael Rice
 
Getting started with Ansible
Getting started with AnsibleGetting started with Ansible
Getting started with AnsibleIvan Serdyuk
 
Create Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantCreate Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantBrian Hogan
 
Instruction: dev environment
Instruction: dev environmentInstruction: dev environment
Instruction: dev environmentSoshi Nemoto
 
Getting Started with Ansible
Getting Started with AnsibleGetting Started with Ansible
Getting Started with AnsibleAhmed AbouZaid
 
Application Deployment Using Ansible
Application Deployment Using AnsibleApplication Deployment Using Ansible
Application Deployment Using AnsibleCliffano Subagio
 
Local Dev on Virtual Machines - Vagrant, VirtualBox and Ansible
Local Dev on Virtual Machines - Vagrant, VirtualBox and AnsibleLocal Dev on Virtual Machines - Vagrant, VirtualBox and Ansible
Local Dev on Virtual Machines - Vagrant, VirtualBox and AnsibleJeff Geerling
 
EC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and PackerEC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and PackerGeorge Miranda
 
Learn basic ansible using docker
Learn basic ansible using dockerLearn basic ansible using docker
Learn basic ansible using dockerLarry Cai
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012Carlos Sanchez
 

What's hot (20)

201904 websocket
201904 websocket201904 websocket
201904 websocket
 
Go Faster with Ansible (AWS meetup)
Go Faster with Ansible (AWS meetup)Go Faster with Ansible (AWS meetup)
Go Faster with Ansible (AWS meetup)
 
Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)Ansible v2 and Beyond (Ansible Hawai'i Meetup)
Ansible v2 and Beyond (Ansible Hawai'i Meetup)
 
Ansible 2.0 - How to use Ansible to automate your applications in AWS.
Ansible 2.0 - How to use Ansible to automate your applications in AWS.Ansible 2.0 - How to use Ansible to automate your applications in AWS.
Ansible 2.0 - How to use Ansible to automate your applications in AWS.
 
快快樂樂用Homestead
快快樂樂用Homestead快快樂樂用Homestead
快快樂樂用Homestead
 
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоIaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
 
Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)
 
Introduction to vSphere APIs Using pyVmomi
Introduction to vSphere APIs Using pyVmomiIntroduction to vSphere APIs Using pyVmomi
Introduction to vSphere APIs Using pyVmomi
 
Getting started with Ansible
Getting started with AnsibleGetting started with Ansible
Getting started with Ansible
 
Fabric: A Capistrano Alternative
Fabric:  A Capistrano AlternativeFabric:  A Capistrano Alternative
Fabric: A Capistrano Alternative
 
Deployment automation
Deployment automationDeployment automation
Deployment automation
 
Create Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantCreate Development and Production Environments with Vagrant
Create Development and Production Environments with Vagrant
 
Instruction: dev environment
Instruction: dev environmentInstruction: dev environment
Instruction: dev environment
 
Getting Started with Ansible
Getting Started with AnsibleGetting Started with Ansible
Getting Started with Ansible
 
Application Deployment Using Ansible
Application Deployment Using AnsibleApplication Deployment Using Ansible
Application Deployment Using Ansible
 
Local Dev on Virtual Machines - Vagrant, VirtualBox and Ansible
Local Dev on Virtual Machines - Vagrant, VirtualBox and AnsibleLocal Dev on Virtual Machines - Vagrant, VirtualBox and Ansible
Local Dev on Virtual Machines - Vagrant, VirtualBox and Ansible
 
EC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and PackerEC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and Packer
 
Ansible best practices
Ansible best practicesAnsible best practices
Ansible best practices
 
Learn basic ansible using docker
Learn basic ansible using dockerLearn basic ansible using docker
Learn basic ansible using docker
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012
 

Similar to Symfony finally swiped right on envvars

Docker Security workshop slides
Docker Security workshop slidesDocker Security workshop slides
Docker Security workshop slidesDocker, Inc.
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabricandymccurdy
 
Writing & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp BostonWriting & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp BostonPuppet
 
A Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy SystemA Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy Systemadrian_nye
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsMarcelo Pinheiro
 
Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetAchieve Internet
 
Digital Forensics and Incident Response in The Cloud Part 3
Digital Forensics and Incident Response in The Cloud Part 3Digital Forensics and Incident Response in The Cloud Part 3
Digital Forensics and Incident Response in The Cloud Part 3Velocidex Enterprises
 
Bangpypers april-meetup-2012
Bangpypers april-meetup-2012Bangpypers april-meetup-2012
Bangpypers april-meetup-2012Deepak Garg
 
Comment améliorer le quotidien des Développeurs PHP ?
Comment améliorer le quotidien des Développeurs PHP ?Comment améliorer le quotidien des Développeurs PHP ?
Comment améliorer le quotidien des Développeurs PHP ?AFUP_Limoges
 
Getting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and SymfonyGetting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and SymfonyAndré Rømcke
 
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013grim_radical
 
Postgres the hardway
Postgres the hardwayPostgres the hardway
Postgres the hardwayDave Pitts
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiJérémy Derussé
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725miguel dominguez
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725MortazaJohari
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Yevgeniy Brikman
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php PresentationAlan Pinstein
 
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Carlos Sanchez
 

Similar to Symfony finally swiped right on envvars (20)

One-Man Ops
One-Man OpsOne-Man Ops
One-Man Ops
 
Docker Security workshop slides
Docker Security workshop slidesDocker Security workshop slides
Docker Security workshop slides
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabric
 
Writing & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp BostonWriting & Sharing Great Modules - Puppet Camp Boston
Writing & Sharing Great Modules - Puppet Camp Boston
 
A Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy SystemA Fabric/Puppet Build/Deploy System
A Fabric/Puppet Build/Deploy System
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability Systems
 
Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and Puppet
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 
Digital Forensics and Incident Response in The Cloud Part 3
Digital Forensics and Incident Response in The Cloud Part 3Digital Forensics and Incident Response in The Cloud Part 3
Digital Forensics and Incident Response in The Cloud Part 3
 
Bangpypers april-meetup-2012
Bangpypers april-meetup-2012Bangpypers april-meetup-2012
Bangpypers april-meetup-2012
 
Comment améliorer le quotidien des Développeurs PHP ?
Comment améliorer le quotidien des Développeurs PHP ?Comment améliorer le quotidien des Développeurs PHP ?
Comment améliorer le quotidien des Développeurs PHP ?
 
Getting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and SymfonyGetting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and Symfony
 
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
 
Postgres the hardway
Postgres the hardwayPostgres the hardway
Postgres the hardway
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
 
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
 

Recently uploaded

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 

Recently uploaded (20)

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

Symfony finally swiped right on envvars

  • 1. Or,“why do we keep baking secrets into our artifacts?” Symfony finally swiped right on envvars
  • 2. Or,“why do we keep baking secrets into our artifacts?” Symfony finally swiped right on envvars just a collection of cool gifs
  • 3.
  • 4. Hi, I’m Sam ● Long time listener, first time caller. ● Co-organiser of this group. ● Using Symfony since 2.0 beta. ● Day job - ops @ REA. ● Docker & build automation fanboy. ● Have committed terrible atrocities with VCS and build systems in the past.
  • 5. Symfony is not your grandma’s framework unique as a web framework
  • 6. Most frameworks re-read config at boot. (Every. page. load.)
  • 7. $ bin/elasticsearch ...waits 30 seconds... $ curl localhost:9200 [timeout] ...waits 30 more seconds... $ curl localhost:9200 [timeout]
  • 8. Symfony compiles the DI container to PHP, including all config values.
  • 10. What is a secret?
  • 11.
  • 12. ● Database credentials ● SMTP creds ● Payment gateway keys ● AWS credentials ● SMS tokens ● EDM service API keys Beyond 11 herbs and spices
  • 13. The modern app has so many.. ● S3 bucket names ● SSH or deploy keys ● JWT keys or certificates ● Service n’s API key ● Other internal system hostnames But really, an application secret is anything you wouldn’t put directly in the HTML markup itself.
  • 14. Here’s why we get a bad rep as php developers[1][2] … 1: I’ve seen all of these examples used 2: you probably have, too
  • 15.
  • 16. <?php class Config { const LIVE_DATABASE_STRING = 'mysql://root:root@localhost:3306/pro const TEST_DATABASE_STRING = 'mysql://root:root@localhost:3306/tes public static function getDatabaseString() { // @TODO add magic to determine environment return self::LIVE_DATABASE_STRING; } // ...etc The know it all “pattern”
  • 17. The build it & they’ll come “pattern” 1. put your prod & test values in a config file 2. run “make config” or some other magic build script 3. generate PHP from template: <?php class Config { const DATABASE_STRING = '{{ database_string }}'; public static function getDatabaseString() { return self::DATABASE_STRING;
  • 18.
  • 19. dropping a prod database on a misconfigured test site. - my biggest professional fuck up. probably?
  • 20. config_dev.yml: doctrine: dbal: url: 'mysql://root:root@localhost:3306/dev' The config.yml is the new Config class…. “pattern” config_prod.yml: doctrine: dbal: url: 'mysql://root:fk!ash#@localhost:3306/pr
  • 21. Into today*... * as is common in many Symfony projects
  • 22.
  • 23. Note: This is the best of the bad, but Symfony makes it insecure & hard to update. 1. define your config keys in a file called parameters.yml.dist, set sane defaults 2. store the actual configuration on S3 / build servers / CI / somewhere else 3. at build-time, copy the file in & build the container (cache-warm) The Fabien told me to “pattern”
  • 24.
  • 25. OK. What’s wrong with this? How secure is your CI? Who has access to wherever the parameter values are stored?
  • 26. OK. What’s wrong with this? Rolling the keys means re-deploying the application.
  • 27. OK. What’s wrong with this? Secrets are written into the compiled Container class file. Try it yourself: $ grep “database.host” var/cache/prod/*.php
  • 28. OK. What’s wrong with this? Creating new deployments is hard.
  • 29. OK. What’s wrong with this? Production artifact differs to test.
  • 30. OK, so what’s the answer?
  • 31.
  • 32. Introducing environment variables ✅ Easy to set up in the app ✅ Functions just like another parameter ✅ Not compiled into the container ✅ Like other parameters, allows default values to be set ✅ Updating values is as simple as updating wherever it’s stored & reload PHP
  • 33. Introducing environment variables ❌ Can’t access outside services - i.e. controllers etc - may require app refactoring ❌ Can be difficult to implement if you run your app outside of Docker ❌ Some libraries don’t quite support envvars yet (there’s a workaround though!)
  • 35. parameters: env(DATABASE_URL): mysql://root:root@db:3306/symfony?charset= env(MAILER_HOST): smtp.sparkpostmail.com env(MAILER_PORT): 587 env(MAILER_USER): SMTP_Injection env(MAILER_PASS): env(SECRET): ThisTokenIsNotSoSecretChangeIt short_link_host: %env(SHORT_LINK_HOST)% env(SHORT_LINK_HOST): fallback.local Default values, get overridden if provided in the env How I dealt with libraries that don’t support env vars or values needed in controllers Note the structure around the name
  • 36. doctrine: dbal: url: '%env(DATABASE_URL)%' orm: auto_generate_proxy_classes: '%kernel.debug%' naming_strategy: doctrine.orm.naming_strategy.underscore auto_mapping: true swiftmailer: transport: "smtp" host: "%env(MAILER_HOST)%" port: "%env(MAILER_PORT)%" username: "%env(MAILER_USER)%" password: "%env(MAILER_PASS)%" spool: { type: "memory" } How they’re used - in configuration YAML files...
  • 37. services: amazon_s3: class: AwsS3S3Client arguments: - credentials: key: "%env(AWS_ACCESS_KEY_ID)%" secret: "%env(AWS_ACCESS_SECRET_KEY)%" region: "%env(AWS_REGION)%" version: "2006-03-01" How they’re used - in service configuration files...
  • 38. While you’re porting ● Consider what values actually change between deployment environments ● Anything that doesn’t change, should go into config.yml, config_dev.yml or config_prod.yml (a la current standard edition practice). ● Anything that changes is a good candidate to live in the environment.
  • 39. Any gotchas? ● Need to defer making decisions on anything that changes per-deployment until later. i.e. any decisions made in a container extension. ● Dynamic parameters don’t solve this %param% => %env(PARAM)% ● If it’s your bundle/extension, you can use factory services to work around this.
  • 40. The Dotenv component in 3.3 ● Symfony flex uses it out of the box! ● A small class that is added in your app/app_dev.php and console scripts ● Provides env-var like support in places you can’t easily set variables (dev!) ● In Flex, it replaces the parameters.yml paradigm ● Relatively easy to back-port into the full-stack framework
  • 41. Or…
  • 42.
  • 43. You can use docker in development!
  • 44.
  • 45. It’s not (all) about security.
  • 46.
  • 47. Environment vars are not perfect ● Does not solve security for anyone with access to the machine. ● Can still be accessed from outside your app - i.e. anything in shell_exec() calls. ● The PHP user or someone on CLI can expose to another program. ● Any insecure libraries in your app can access it, too. ● Can unintentionally turn up in logs, the Symfony profiler, etc. ● The plain-text values are probably still stored somewhere.
  • 48. How do I make it better? ● Current PR: github/symfony/symfony#23901 (due 3.4) adds features to support docker/kubernetes secrets & make it extendable. ● Once it’s available to us, it might be like this… ○ on AWS? KMS-encrypted envvars or SSM Param. Store. ○ Not AWS? G-Cloud KMS, or other open-source, e.g. Hashicorp Vault, Pinterest Knox, Lyft Confidant. ● In the meantime: do you host on AWS? Use KMS-encrypted environment variables or fetch from SSM Param. Store at container boot.
  • 49. ● Any of these principles a surprise? Read about 12-factor apps ● Segment have a great write-up on managing secrets on AWS on their blog. ● KMS-ed envvars (enc. strings): REA’s Shush is a tiny go library to help. ● SSM param. store (central management): Segment’s Chamber can help. ● Taking inspo from k8s, Docker swarm mode now has secrets built-in. ● Not using Docker? Can be quite complicated to set env across multiple users + daemons. Apache, and CLI users share a syntax, PHP-FPM is different. ● Example of porting a Symfony app to Docker - for the adventurous. Further reading & tools
  • 50. thank you. stalky stalk: @sammyjarrett or linkedin.com/in/samjarrett more detail and these slides published at samjarrett.com.au/swipe-right

Editor's Notes

  1. Since 2.0 beta, before all the current patterns we now use existed, before the documentation was any good. Terrible atrocities: here to atone, really.
  2. For PHP apps, booting refers to the app loading on each page load Not just something that occurs in PHP. Ruby, Python, Node, etc all do this. In comparison, Symfony demands that you compile the application before you boot it. We call it building the container. Or clearing the cache. Symfony steals a lot from Java, which also also suffers from the same issue, but you notice it differently... Here’s something I’m sure we’re all familiar with...
  3. This is familiar with any time you’ve ever booted a java app. Building the configuration tree and configuring the services is mostly why they take so long to start accepting traffic!
  4. Which gives us a good speed improvement because the app doesn’t have to load all of it’s configuration and build the container at runtime! This creates a big problem when we have complex build and deploy processes that need to operate at scale (how do you deploy to 20+ instances quickly? prebuild!) and still protect secret values Modern deployment practices emphasise keeping the artifact static between environments, to be able to more easily replicate issues back in development or testing environments. Container compilation means that we can’t guarantee that our artifact compiles correctly or that it is exactly the same in production. So, how do we solve this in symfony?
  5. But this naturally creates issues when we have secrets in our apps, and yep, the modern app has a lot of them
  6. What is a secret? Secrets can be any form of data that you wouldn’t want to be widely spread around.
  7. Internal hostnames (i.e. unprotected internal systems you’re hiding): redis, memcached, finance systems, etc Lead developer’s email address (for emailing emerging issues, I guess) Pagerduty/OpsGenie alert topics/email address (don’t want these abused overnight waking up on call staff!) Slack tokens Summary: secret is anytthing you wouldn’t want to put in the markup
  8. Create a single class or factory class, and delegate responsibility for it to provide you with answers, Ultimately embedding the secret for all environments in it. Compromise here on either test or production means all of your secrets are gone.
  9. Use ini, json, yaml, java.properties style or some other configuration format to specify all of your values Create a php-class as a template full of placeholders that a template parser can quickly generate the final value for you Generate the PHP from the template before deploying (as part of a build or deploy process) Include the final configuration (without the config file) as part of your deployment artifact. Profit?
  10. Since we’re having an amnesty session, here’s my big professional mistake.
  11. Dropping a production database because a test-site was misconfigured to use it by one of the above secret management methods (you can guess) Let’s have some drinks after and I’ll expand on the unprofessional ones.
  12. Same management principal as the config class (“know it all”), finally we add some Symfony flair! Use config_dev.yml and config_prod.yml to store secrets for each environment Largely seen in remnants of old Symfony 2.0 projects, from before the framework didn’t suggest a way of swapping values out yet (i.e. pre-parameters.ini) Some apps that have existed since then and just been upgraded still contain bits and pieces of this
  13. No disrespect to Fabien. He’s a super smart guy and this works pretty good. But we evolve.
  14. Symfony provides such a simple way forward and we all go running to do it! Let’s make everything a parameter! What’s wrong with this?
  15. CI systems can be hacked. If it’s in S3 or on a server somewhere that the CI can access, can others? Do you audit access to this?
  16. In the midst of a security incident, this may allow an unacceptable delay to roll a pivotal secret, or mean that your application “goes down” or has degraded functionality until the build/deploy completes. If the key is something critical (e.g. database), you can’t do a rolling deploy.
  17. Lost your DB creds? You can recover them in var/cache/prod/appProdContainer.php! Great idea until the framework actually gained traction and then become subject to every hacker and their dog knowing how to do this.
  18. Want to add a pre-prod? Or test a new feature on prod-like infra? New deployments now involve: updating your CI & build process, building a new artifact, updating your deployment process & tools
  19. How sure are you that the issue doesn’t exist solely on production? Can developers drag the exact artifact down to their machine to replicate?
  20. Wow this project was inconsistent with config values and quotes
  21. In symfony we think of app environments, and try to keep agnostic to deployment environments (test server is still prod app environment), but for this, consider deployment envs.
  22. Biggest challenge is dev environments where setting envvars is traditionally hard
  23. I’ve talked a bit about security, but it’s not really. And her’es the big gotcha
  24. Has the same flaws as any other parameter, plus a few new ones