@danaluther
Keep it Secret, Keep it Safe
Docker Secrets and DI (Containers)
https://joind.in/talk/78c5b
https://github.com/DanaLuther/kiskis
@danaluther
What are we keeping secret?
All the things? (no… but de
fi
nitely the important things)
@danaluther
What are we keeping secret?
All the things? (no… but de
fi
nitely the important things)
• File Based Credentials
@danaluther
What are we keeping secret?
All the things? (no… but de
fi
nitely the important things)
• File Based Credentials
• SSH key
fi
les
@danaluther
What are we keeping secret?
All the things? (no… but de
fi
nitely the important things)
• File Based Credentials
• SSH key
fi
les
• Json auth
fi
les
@danaluther
What are we keeping secret?
All the things? (no… but de
fi
nitely the important things)
• File Based Credentials
• SSH key
fi
les
• Json auth
fi
les
• Variable Credentials
@danaluther
What are we keeping secret?
All the things? (no… but de
fi
nitely the important things)
• File Based Credentials
• SSH key
fi
les
• Json auth
fi
les
• Variable Credentials
• API keys and tokens
@danaluther
What are we keeping secret?
All the things? (no… but de
fi
nitely the important things)
• File Based Credentials
• SSH key
fi
les
• Json auth
fi
les
• Variable Credentials
• API keys and tokens
• Any value that could compromise security / grant access to your data or
accounts.
@danaluther
Isn't it already safe?
…Ish. It depends - how are you storing it currently?
@danaluther
Isn't it already safe?
…Ish. It depends - how are you storing it currently?
• Storing credentials directly into a repo
@danaluther
Isn't it already safe?
…Ish. It depends - how are you storing it currently?
• Storing credentials directly into a repo
• Readable by anyone with access to that repo
@danaluther
Isn't it already safe?
…Ish. It depends - how are you storing it currently?
• Storing credentials directly into a repo
• Readable by anyone with access to that repo
• Exposed in coverage reports or anything that includes the source code in
analysis or reporting displays
@danaluther
Isn't it already safe?
…Ish. It depends - how are you storing it currently?
• Storing credentials directly into a repo
• Readable by anyone with access to that repo
• Exposed in coverage reports or anything that includes the source code in
analysis or reporting displays
• Storing credentials in ENV variables
@danaluther
Isn't it already safe?
…Ish. It depends - how are you storing it currently?
• Storing credentials directly into a repo
• Readable by anyone with access to that repo
• Exposed in coverage reports or anything that includes the source code in
analysis or reporting displays
• Storing credentials in ENV variables
• Exposed via phpinfo, server dumps, or to anyone who has compromised
the server
@danaluther
Isn't it already safe?
…Ish. It depends - how are you storing it currently?
• Storing credentials directly into a repo
• Readable by anyone with access to that repo
• Exposed in coverage reports or anything that includes the source code in
analysis or reporting displays
• Storing credentials in ENV variables
• Exposed via phpinfo, server dumps, or to anyone who has compromised
the server
• Not static and has the potential to be modi
fi
ed nefariously
@danaluther
Does it really matter?
I don’t know … does it?
@danaluther
Does it really matter?
I don’t know … does it?
• How important is the service or information being used?
@danaluther
Does it really matter?
I don’t know … does it?
• How important is the service or information being used?
• How big is the impact if that service is accessed by another?
@danaluther
Does it really matter?
I don’t know … does it?
• How important is the service or information being used?
• How big is the impact if that service is accessed by another?
• Is the credential the sole key to access, or is does the service have additional
factors in play?
@danaluther
Does it really matter?
I don’t know … does it?
• How important is the service or information being used?
• How big is the impact if that service is accessed by another?
• Is the credential the sole key to access, or is does the service have additional
factors in play?
• What is the risk level compared to the technical debt?
@danaluther
Does it really matter?
I don’t know … does it?
• How important is the service or information being used?
• How big is the impact if that service is accessed by another?
• Is the credential the sole key to access, or is does the service have additional
factors in play?
• What is the risk level compared to the technical debt?
• Does the information get published into your application as part of the public
UI?
@danaluther
Sample API Object
Class with public API credential property
class SampleObject


{


	
public string $myApiKey = 'ABC1234';


	
public function connect()


	
{


	
	
/
/
Do something with $myApiKey here


	
}


}
@danaluther
Sample API Object
Class with public API credential property
class SampleObject


{


	
public string $myApiKey = 'ABC1234';


	
public function connect()


	
{


	
	
/
/
Do something with $myApiKey here


	
}


}


new ExampleSampleObject()
@danaluther
Sample API Object v2
Class with API credential property
class SampleObjectMoreSecure


{


	
private string $myApiKey = 'ABC1234';


	
public function connect()


	
{


	
	
/
/
Do something with $myApiKey here


	
}


}
@danaluther
Sample API Object v2
Class with API credential property
class SampleObjectMoreSecure


{


	
private string $myApiKey = 'ABC1234';


	
public function connect()


	
{


	
	
/
/
Do something with $myApiKey here


	
}


}


new ExampleSampleObjectMoreSecure()
@danaluther
Sample API Object v3
Class with constructed private API credential property
class SampleObjectConstructed


{


	
private string $_myApiKey;


	
public function __construct(string $apiKey)


	
{


	
	
$this
-
>
_myApiKey = $apiKey;


	
}


	
public function connect()


	
{


	
	
/
/
Do something


	
}


}
@danaluther
Sample API Object v3
Class with constructed private API credential property
class SampleObjectConstructed


{


	
private string $_myApiKey;


	
public function __construct(string $apiKey)


	
{


	
	
$this
-
>
_myApiKey = $apiKey;


	
}


	
public function connect()


	
{


	
	
/
/
Do something


	
}


}
new ExampleSampleObjectConstructed('Someothervalue')
@danaluther
Sample API Object v3 with $_ENV
Class with constructed private API credential property
class SampleObjectConstructed


{


	
private string $_myApiKey;


	
public function __construct(string $apiKey)


	
{


	
	
$this
-
>
_myApiKey = $apiKey;


	
}


	
public function connect()


	
{


	
	
/
/
Do something


	
}


}
@danaluther
Sample API Object v3 with $_ENV
Class with constructed private API credential property
class SampleObjectConstructed


{


	
private string $_myApiKey;


	
public function __construct(string $apiKey)


	
{


	
	
$this
-
>
_myApiKey = $apiKey;


	
}


	
public function connect()


	
{


	
	
/
/
Do something


	
}


}
new ExampleSampleObjectConstructed($_ENV['MY_SECRET_KEY'])
@danaluther
Sample API Object v3 with $_ENV
Class with constructed private API credential property
class SampleObjectConstructed


{


	
private string $_myApiKey;


	
public function __construct(string $apiKey)


	
{


	
	
$this
-
>
_myApiKey = $apiKey;


	
}


	
public function connect()


	
{


	
	
/
/
Do something


	
}


}
new ExampleSampleObjectConstructed($_ENV['MY_SECRET_KEY'])
@danaluther
Dependency Injection Containers
So, what is it and how does it help us??
@danaluther
Dependency Injection Containers
So, what is it and how does it help us??
• Does NOT help to solve the issue of
fi
le based credentials.
@danaluther
Dependency Injection Containers
So, what is it and how does it help us??
• Does NOT help to solve the issue of
fi
le based credentials.
• Does help to solve the issue of class based or variable credential strings.
@danaluther
Dependency Injection Containers
So, what is it and how does it help us??
• Does NOT help to solve the issue of
fi
le based credentials.
• Does help to solve the issue of class based or variable credential strings.
• Creates a map that de
fi
nes the default properties to be assigned to an object
when that object is created via the container.
@danaluther
Don’t reinvent the wheel.
https://packagist.org
@danaluther
Add your DI package to composer
composer.json
{


"require": {


"yiisoft/di": "^3.0.x
-
dev",


"yiisoft/injector": "^1.0",


"yiisoft/definitions": "^3.0.x
-
dev"


}


}
@danaluther
Install the composer packages
docker run --rm -v $PWD:/app composer update
https://hub.docker.com/_/composer
@danaluther
Sample API Object v3 with $_ENV via DI
Constructor moved to DI Container
require 'vendor/autoload.php';


use YiisoftDiContainer;


$container = new Container([


ExampleSampleObjectConstructed
:
:
class
=
>
[


	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
'__construct()'
=
>
[$_ENV['MY_SECRET_KEY']]


],


]);
@danaluther
Sample API Object v3 with $_ENV via DI
Constructor moved to DI Container
require 'vendor/autoload.php';


use YiisoftDiContainer;


$container = new Container([


ExampleSampleObjectConstructed
:
:
class
=
>
[


	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
'__construct()'
=
>
[$_ENV['MY_SECRET_KEY']]


],


]);
@danaluther
Sample API Object v3 with $_ENV via DI
Constructor moved to DI Container
require 'vendor/autoload.php';


use YiisoftDiContainer;


$container = new Container([


ExampleSampleObjectConstructed
:
:
class
=
>
[


	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
'__construct()'
=
>
[$_ENV['MY_SECRET_KEY']]


],


]); $container
-
>
get(ExampleSampleObjectConstructed
:
:
class)
@danaluther
But is it secret? Is it safe?
Lets check those $_ENV vars …
@danaluther
But is it secret? Is it safe?
Lets check those $_ENV vars …
@danaluther
Docker Secrets
What are they and how do they help us?
@danaluther
Docker Secrets
What are they and how do they help us?
• Does help to solve the issue of
fi
le based credentials.
@danaluther
Docker Secrets
What are they and how do they help us?
• Does help to solve the issue of
fi
le based credentials.
• Does help to solve the issue of class based or variable credential strings.
@danaluther
Docker Secrets
What are they and how do they help us?
• Does help to solve the issue of
fi
le based credentials.
• Does help to solve the issue of class based or variable credential strings.
• Created as elements of a Docker stack and written to read-only
fi
les in the
container they are attached to.
@danaluther
Docker Secrets
What are they and how do they help us?
• Does help to solve the issue of
fi
le based credentials.
• Does help to solve the issue of class based or variable credential strings.
• Created as elements of a Docker stack and written to read-only
fi
les in the
container they are attached to.
• Can only be be modi
fi
ed by the stack when a new container is created.
@danaluther
Docker Secrets
What are they and how do they help us?
• Does help to solve the issue of
fi
le based credentials.
• Does help to solve the issue of class based or variable credential strings.
• Created as elements of a Docker stack and written to read-only
fi
les in the
container they are attached to.
• Can only be be modi
fi
ed by the stack when a new container is created.
• Cannot be exposed through inspection via the stack or parent machine. Only
visible in the container where it has been mounted.
@danaluther
What is Docker?
(Jumped ahead there didn’t I…)
https://www.docker.com
@danaluther
What is Docker?
Docker Hierarchy
https://hub.docker.com
@danaluther
What is Docker?
Docker Hierarchy
Image Container Service Stack
https://hub.docker.com
@danaluther
Basic Stack for PHP Apache on :8080
docker-compose.yml
https://docs.docker.com/compose/compose-
fi
le/
version: “3.7"


services:


php:


image: php:7.4-apache


ports:


- 8080
:
80


volumes:


- ./src:/var/
w
w
w
/html
@danaluther
version: “3.7"


services:


php:


image: php:7.4-apache


ports:


- 8080
:
80


volumes:


- ./src:/var/
w
w
w
/html


command:[


‘bash’, ‘
-
c’,


‘docker
-
php
-
ext
-
install
-
j$$(nproc) mysqli pdo_mysql
&
&
apache2-foreground’


]


db:


image: mysql


environment:


- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd


secrets:


- db_pwd


secrets:


db_pwd:


file: ./root_db_password.txt
@danaluther
version: “3.7"


services:


php:


image: php:8.0-apache


ports:


- 8080
:
80


volumes:


- ./src:/var/
w
w
w
/html


command:[


‘bash’, ‘
-
c’,


‘docker
-
php
-
ext
-
install
-
j$$(nproc) mysqli pdo_mysql
&
&
apache2-foreground’


]


db:


image: mysql


environment:


- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd


secrets:


- db_pwd


secrets:


db_pwd:


file: ./root_db_password.txt
@danaluther
version: “3.7"


services:


php:


image: php:8.1-rc—apache


ports:


- 8080
:
80


volumes:


- ./src:/var/
w
w
w
/html


command:[


‘bash’, ‘
-
c’,


‘docker
-
php
-
ext
-
install
-
j$$(nproc) mysqli pdo_mysql
&
&
apache2-foreground’


]


db:


image: mysql


environment:


- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd


secrets:


- db_pwd


secrets:


db_pwd:


file: ./root_db_password.txt
@danaluther
Deploy the Stack on a Swarm
(Group of machines … or just one machine)
> docker stack deploy
-
c docker
-
compose-8.yml test
> docker swarm init
@danaluther
Voila!
http://localhost:8080
@danaluther
Voila!
http://localhost:8080
@danaluther
No swarm? No problem…
> docker
-
compose up
(Well, mostly no problem. No services list, secrets list, etc)
@danaluther
No swarm? No problem…
> docker
-
compose up
(Well, mostly no problem. No services list, secrets list, etc)
@danaluther
@danaluther
Creating a Docker Secret
The secret is in the stack…
…


db:


image: mysql


environment:


- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd


secrets:


- db_pwd


secrets:


db_pwd:


file: ./root_db_password.txt
@danaluther
Creating a Docker Secret
The secret is in the stack…
…


db:


image: mysql


environment:


- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd


secrets:


- db_pwd


secrets:


db_pwd:


file: ./root_db_password.txt
@danaluther
Check the containers…
docker container ls
@danaluther
Check the containers…
docker container ls
@danaluther
Inspect the container for the secret
docker container inspect
@danaluther
Inspect the container for the secret
docker container inspect
> docker container inspect $(docker ps
-
lq
-
f name=test_db)
> docker container inspect ff8dc39f919f
> docker container inspect test_db.1.l8enz0qx7x8zci4156gh7i0qy
@danaluther
Inspect the container for the secret
docker container inspect
> docker container inspect kiskis_db_1
> docker container inspect 378020331e87
> docker container inspect $(docker ps
-
lq
-
f name=test_db)
> docker container inspect ff8dc39f919f
> docker container inspect test_db.1.l8enz0qx7x8zci4156gh7i0qy
@danaluther
Inspect the container for the secret
docker container inspect
@danaluther
Inspect the container for the secret
docker container inspect
@danaluther
Inspect the container for the secret
docker container inspect
@danaluther
What's actually in the Secret?
@danaluther
What's actually in the Secret?
@danaluther
Can the container change the secret?
Nope!!
@danaluther
Can *I* change the secret?
Yes, yes I can.
@danaluther
Can *I* change the secret?
Yes, yes I can.
If I used docker stack deploy.
@danaluther
Updating a Docker Secret
(Ok, you can’t actually update it, you have to replace it.)
> docker secret create db_pwd.2 updatedcontent.txt
@danaluther
Updating a Docker Secret
(Ok, you can’t actually update it, you have to replace it.)
> docker service update
-
-
secret
-
rm test_db_pwd 


-
-
secret
-
add src=db_pwd.2,target=db_pwd test_db
@danaluther
Confirm the update
Updating the service launched a new container with a new secret.
New:
Original:
@danaluther
Great, but I don’t care about the database…
Right - lets put the secret to use in our DI container
@danaluther
Great, but I don’t care about the database…
Right - lets put the secret to use in our DI container
@danaluther
Sample API Object v3 with $_ENV via DI
Constructor moved to DI Container
require 'vendor/autoload.php';


use YiisoftDiContainer;


$container = new Container([


ExampleSampleObjectConstructed
:
:
class
=
>
[


	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
'__construct()'
=
>
[$_ENV['MY_SECRET_KEY']]


],


]); $container
-
>
get(ExampleSampleObjectConstructed
:
:
class)
@danaluther
Sample API Object v3 with $_ENV via DI
Constructor moved to DI Container
require 'vendor/autoload.php';


use YiisoftDiContainer;


$container = new Container([


ExampleSampleObjectConstructed
:
:
class
=
>
[


	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
'__construct()'
=
>
[$_ENV['MY_SECRET_KEY']]


],


]); $container
-
>
get(ExampleSampleObjectConstructed
:
:
class)
@danaluther
PHP stack with secrets
version: "3.7"


services:


php:


image: php:8.1-rc
-
apache


ports:


- 8081
:
80


volumes:


- ./src:/var/
w
w
w
/html


environment:


- MY_SECRET_KEY=SomeKeyValue


secrets:


- hiddenkey


- hiddenkey2


secrets:


hiddenkey:


file: ./secrets/secret
-
key
-
val.txt


hiddenkey2
:


file: ./secrets/secret
-
key
-
val2.txt
@danaluther
Deploy the Stack on a Swarm
(Don’t need to init, just re-deploy for updates)
> docker stack deploy
-
c docker
-
compose-8-1-nodb.yml test
@danaluther
Sample API Object v3 with secret via DI
Container populated from secret
require 'vendor/autoload.php';


use YiisoftDiContainer;


$container = new Container([


ExampleSampleObjectConstructed
:
:
class
=
>
[


	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
'__construct()'
=
>
[file_get_contents('/run/secrets/hiddenkey')]


],


]);
@danaluther
Sample API Object v3 with secret via DI
Container populated from secret
require 'vendor/autoload.php';


use YiisoftDiContainer;


$container = new Container([


ExampleSampleObjectConstructed
:
:
class
=
>
[


	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
'__construct()'
=
>
[file_get_contents('/run/secrets/hiddenkey')]


],


]); $container
-
>
get(ExampleSampleObjectConstructed
:
:
class)
@danaluther
Define multiple objects in the container
Multiple classes, multiple con
fi
gurations of one class
$container = new Container([


	
ExampleSampleObjectConstructed
:
:
class
=
>
[


	
	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
	
'__construct()'
=
>
[file_get_contents('/run/secrets/hiddenkey')]


	
],


	
ExamplePartnerConfigIdentifier
:
:
OPT_CONFIG_1
=
>
[


	
	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
	
'__construct()'
=
>
[file_get_contents('/run/secrets/hiddenkey2')]


	
],


	
ExamplePartnerConfigIdentifier
:
:
OPT_CONFIG_2
=
>
[


	
	
'class'
=
>
ExampleSampleObjectConstructed
:
:
class,


	
	
'__construct()'
=
>
['You can read me in the source repo.']


	
],


]);
@danaluther
Using constants to keep things tidy
(Yes, it wants to be an enum, but we’re 7.4 compatible currently)
class PartnerConfigIdentifier


{


	
public const DEFAULT_CONFIG = self
:
:
class.':default';


	
public const OPT_CONFIG_1 = self
:
:
class.':opt1';


	
public const OPT_CONFIG_2 = self
:
:
class.':opt2';


	
public const OPT_CONFIG_3 = self
:
:
class.':opt3';


}
@danaluther
Using constants to keep things tidy
(Yes, it wants to be an enum, but we’re 7.4 compatible currently)
class PartnerConfigIdentifier


{


	
public const DEFAULT_CONFIG = self
:
:
class.':default';


	
public const OPT_CONFIG_1 = self
:
:
class.':opt1';


	
public const OPT_CONFIG_2 = self
:
:
class.':opt2';


	
public const OPT_CONFIG_3 = self
:
:
class.':opt3';


}
@danaluther
Create multiple objects via the container
$container
-
>
get(ExampleSampleObjectConstructed
:
:
class);
$container
-
>
get(ExamplePartnerConfigIdentifier
:
:
OPT_CONFIG_1);
$container
-
>
get(ExamplePartnerConfigIdentifier
:
:
OPT_CONFIG_2);
@danaluther
Questions??
Ask now or tweet at me if you think of it later!
https://www.linkedin.com/in/danaluther
dluther@envisageinternational.com
https://joind.in/talk/78c5b
🤔
?
? ?
?
https://github.com/DanaLuther/kiskis

Keep it Secret, Keep it Safe - Docker Secrets and DI

  • 1.
    @danaluther Keep it Secret,Keep it Safe Docker Secrets and DI (Containers) https://joind.in/talk/78c5b https://github.com/DanaLuther/kiskis
  • 2.
    @danaluther What are wekeeping secret? All the things? (no… but de fi nitely the important things)
  • 3.
    @danaluther What are wekeeping secret? All the things? (no… but de fi nitely the important things) • File Based Credentials
  • 4.
    @danaluther What are wekeeping secret? All the things? (no… but de fi nitely the important things) • File Based Credentials • SSH key fi les
  • 5.
    @danaluther What are wekeeping secret? All the things? (no… but de fi nitely the important things) • File Based Credentials • SSH key fi les • Json auth fi les
  • 6.
    @danaluther What are wekeeping secret? All the things? (no… but de fi nitely the important things) • File Based Credentials • SSH key fi les • Json auth fi les • Variable Credentials
  • 7.
    @danaluther What are wekeeping secret? All the things? (no… but de fi nitely the important things) • File Based Credentials • SSH key fi les • Json auth fi les • Variable Credentials • API keys and tokens
  • 8.
    @danaluther What are wekeeping secret? All the things? (no… but de fi nitely the important things) • File Based Credentials • SSH key fi les • Json auth fi les • Variable Credentials • API keys and tokens • Any value that could compromise security / grant access to your data or accounts.
  • 9.
    @danaluther Isn't it alreadysafe? …Ish. It depends - how are you storing it currently?
  • 10.
    @danaluther Isn't it alreadysafe? …Ish. It depends - how are you storing it currently? • Storing credentials directly into a repo
  • 11.
    @danaluther Isn't it alreadysafe? …Ish. It depends - how are you storing it currently? • Storing credentials directly into a repo • Readable by anyone with access to that repo
  • 12.
    @danaluther Isn't it alreadysafe? …Ish. It depends - how are you storing it currently? • Storing credentials directly into a repo • Readable by anyone with access to that repo • Exposed in coverage reports or anything that includes the source code in analysis or reporting displays
  • 13.
    @danaluther Isn't it alreadysafe? …Ish. It depends - how are you storing it currently? • Storing credentials directly into a repo • Readable by anyone with access to that repo • Exposed in coverage reports or anything that includes the source code in analysis or reporting displays • Storing credentials in ENV variables
  • 14.
    @danaluther Isn't it alreadysafe? …Ish. It depends - how are you storing it currently? • Storing credentials directly into a repo • Readable by anyone with access to that repo • Exposed in coverage reports or anything that includes the source code in analysis or reporting displays • Storing credentials in ENV variables • Exposed via phpinfo, server dumps, or to anyone who has compromised the server
  • 15.
    @danaluther Isn't it alreadysafe? …Ish. It depends - how are you storing it currently? • Storing credentials directly into a repo • Readable by anyone with access to that repo • Exposed in coverage reports or anything that includes the source code in analysis or reporting displays • Storing credentials in ENV variables • Exposed via phpinfo, server dumps, or to anyone who has compromised the server • Not static and has the potential to be modi fi ed nefariously
  • 16.
    @danaluther Does it reallymatter? I don’t know … does it?
  • 17.
    @danaluther Does it reallymatter? I don’t know … does it? • How important is the service or information being used?
  • 18.
    @danaluther Does it reallymatter? I don’t know … does it? • How important is the service or information being used? • How big is the impact if that service is accessed by another?
  • 19.
    @danaluther Does it reallymatter? I don’t know … does it? • How important is the service or information being used? • How big is the impact if that service is accessed by another? • Is the credential the sole key to access, or is does the service have additional factors in play?
  • 20.
    @danaluther Does it reallymatter? I don’t know … does it? • How important is the service or information being used? • How big is the impact if that service is accessed by another? • Is the credential the sole key to access, or is does the service have additional factors in play? • What is the risk level compared to the technical debt?
  • 21.
    @danaluther Does it reallymatter? I don’t know … does it? • How important is the service or information being used? • How big is the impact if that service is accessed by another? • Is the credential the sole key to access, or is does the service have additional factors in play? • What is the risk level compared to the technical debt? • Does the information get published into your application as part of the public UI?
  • 22.
    @danaluther Sample API Object Classwith public API credential property class SampleObject { public string $myApiKey = 'ABC1234'; public function connect() { / / Do something with $myApiKey here } }
  • 23.
    @danaluther Sample API Object Classwith public API credential property class SampleObject { public string $myApiKey = 'ABC1234'; public function connect() { / / Do something with $myApiKey here } } new ExampleSampleObject()
  • 24.
    @danaluther Sample API Objectv2 Class with API credential property class SampleObjectMoreSecure { private string $myApiKey = 'ABC1234'; public function connect() { / / Do something with $myApiKey here } }
  • 25.
    @danaluther Sample API Objectv2 Class with API credential property class SampleObjectMoreSecure { private string $myApiKey = 'ABC1234'; public function connect() { / / Do something with $myApiKey here } } new ExampleSampleObjectMoreSecure()
  • 26.
    @danaluther Sample API Objectv3 Class with constructed private API credential property class SampleObjectConstructed { private string $_myApiKey; public function __construct(string $apiKey) { $this - > _myApiKey = $apiKey; } public function connect() { / / Do something } }
  • 27.
    @danaluther Sample API Objectv3 Class with constructed private API credential property class SampleObjectConstructed { private string $_myApiKey; public function __construct(string $apiKey) { $this - > _myApiKey = $apiKey; } public function connect() { / / Do something } } new ExampleSampleObjectConstructed('Someothervalue')
  • 28.
    @danaluther Sample API Objectv3 with $_ENV Class with constructed private API credential property class SampleObjectConstructed { private string $_myApiKey; public function __construct(string $apiKey) { $this - > _myApiKey = $apiKey; } public function connect() { / / Do something } }
  • 29.
    @danaluther Sample API Objectv3 with $_ENV Class with constructed private API credential property class SampleObjectConstructed { private string $_myApiKey; public function __construct(string $apiKey) { $this - > _myApiKey = $apiKey; } public function connect() { / / Do something } } new ExampleSampleObjectConstructed($_ENV['MY_SECRET_KEY'])
  • 30.
    @danaluther Sample API Objectv3 with $_ENV Class with constructed private API credential property class SampleObjectConstructed { private string $_myApiKey; public function __construct(string $apiKey) { $this - > _myApiKey = $apiKey; } public function connect() { / / Do something } } new ExampleSampleObjectConstructed($_ENV['MY_SECRET_KEY'])
  • 31.
    @danaluther Dependency Injection Containers So,what is it and how does it help us??
  • 32.
    @danaluther Dependency Injection Containers So,what is it and how does it help us?? • Does NOT help to solve the issue of fi le based credentials.
  • 33.
    @danaluther Dependency Injection Containers So,what is it and how does it help us?? • Does NOT help to solve the issue of fi le based credentials. • Does help to solve the issue of class based or variable credential strings.
  • 34.
    @danaluther Dependency Injection Containers So,what is it and how does it help us?? • Does NOT help to solve the issue of fi le based credentials. • Does help to solve the issue of class based or variable credential strings. • Creates a map that de fi nes the default properties to be assigned to an object when that object is created via the container.
  • 35.
    @danaluther Don’t reinvent thewheel. https://packagist.org
  • 36.
    @danaluther Add your DIpackage to composer composer.json { "require": { "yiisoft/di": "^3.0.x - dev", "yiisoft/injector": "^1.0", "yiisoft/definitions": "^3.0.x - dev" } }
  • 37.
    @danaluther Install the composerpackages docker run --rm -v $PWD:/app composer update https://hub.docker.com/_/composer
  • 38.
    @danaluther Sample API Objectv3 with $_ENV via DI Constructor moved to DI Container require 'vendor/autoload.php'; use YiisoftDiContainer; $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [$_ENV['MY_SECRET_KEY']] ], ]);
  • 39.
    @danaluther Sample API Objectv3 with $_ENV via DI Constructor moved to DI Container require 'vendor/autoload.php'; use YiisoftDiContainer; $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [$_ENV['MY_SECRET_KEY']] ], ]);
  • 40.
    @danaluther Sample API Objectv3 with $_ENV via DI Constructor moved to DI Container require 'vendor/autoload.php'; use YiisoftDiContainer; $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [$_ENV['MY_SECRET_KEY']] ], ]); $container - > get(ExampleSampleObjectConstructed : : class)
  • 41.
    @danaluther But is itsecret? Is it safe? Lets check those $_ENV vars …
  • 42.
    @danaluther But is itsecret? Is it safe? Lets check those $_ENV vars …
  • 43.
    @danaluther Docker Secrets What arethey and how do they help us?
  • 44.
    @danaluther Docker Secrets What arethey and how do they help us? • Does help to solve the issue of fi le based credentials.
  • 45.
    @danaluther Docker Secrets What arethey and how do they help us? • Does help to solve the issue of fi le based credentials. • Does help to solve the issue of class based or variable credential strings.
  • 46.
    @danaluther Docker Secrets What arethey and how do they help us? • Does help to solve the issue of fi le based credentials. • Does help to solve the issue of class based or variable credential strings. • Created as elements of a Docker stack and written to read-only fi les in the container they are attached to.
  • 47.
    @danaluther Docker Secrets What arethey and how do they help us? • Does help to solve the issue of fi le based credentials. • Does help to solve the issue of class based or variable credential strings. • Created as elements of a Docker stack and written to read-only fi les in the container they are attached to. • Can only be be modi fi ed by the stack when a new container is created.
  • 48.
    @danaluther Docker Secrets What arethey and how do they help us? • Does help to solve the issue of fi le based credentials. • Does help to solve the issue of class based or variable credential strings. • Created as elements of a Docker stack and written to read-only fi les in the container they are attached to. • Can only be be modi fi ed by the stack when a new container is created. • Cannot be exposed through inspection via the stack or parent machine. Only visible in the container where it has been mounted.
  • 49.
    @danaluther What is Docker? (Jumpedahead there didn’t I…) https://www.docker.com
  • 50.
    @danaluther What is Docker? DockerHierarchy https://hub.docker.com
  • 51.
    @danaluther What is Docker? DockerHierarchy Image Container Service Stack https://hub.docker.com
  • 52.
    @danaluther Basic Stack forPHP Apache on :8080 docker-compose.yml https://docs.docker.com/compose/compose- fi le/ version: “3.7" services: php: image: php:7.4-apache ports: - 8080 : 80 volumes: - ./src:/var/ w w w /html
  • 53.
    @danaluther version: “3.7" services: php: image: php:7.4-apache ports: -8080 : 80 volumes: - ./src:/var/ w w w /html command:[ ‘bash’, ‘ - c’, ‘docker - php - ext - install - j$$(nproc) mysqli pdo_mysql & & apache2-foreground’ ] db: image: mysql environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd secrets: - db_pwd secrets: db_pwd: file: ./root_db_password.txt
  • 54.
    @danaluther version: “3.7" services: php: image: php:8.0-apache ports: -8080 : 80 volumes: - ./src:/var/ w w w /html command:[ ‘bash’, ‘ - c’, ‘docker - php - ext - install - j$$(nproc) mysqli pdo_mysql & & apache2-foreground’ ] db: image: mysql environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd secrets: - db_pwd secrets: db_pwd: file: ./root_db_password.txt
  • 55.
    @danaluther version: “3.7" services: php: image: php:8.1-rc—apache ports: -8080 : 80 volumes: - ./src:/var/ w w w /html command:[ ‘bash’, ‘ - c’, ‘docker - php - ext - install - j$$(nproc) mysqli pdo_mysql & & apache2-foreground’ ] db: image: mysql environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd secrets: - db_pwd secrets: db_pwd: file: ./root_db_password.txt
  • 56.
    @danaluther Deploy the Stackon a Swarm (Group of machines … or just one machine) > docker stack deploy - c docker - compose-8.yml test > docker swarm init
  • 57.
  • 58.
  • 59.
    @danaluther No swarm? Noproblem… > docker - compose up (Well, mostly no problem. No services list, secrets list, etc)
  • 60.
    @danaluther No swarm? Noproblem… > docker - compose up (Well, mostly no problem. No services list, secrets list, etc)
  • 61.
  • 62.
    @danaluther Creating a DockerSecret The secret is in the stack… … db: image: mysql environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd secrets: - db_pwd secrets: db_pwd: file: ./root_db_password.txt
  • 63.
    @danaluther Creating a DockerSecret The secret is in the stack… … db: image: mysql environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd secrets: - db_pwd secrets: db_pwd: file: ./root_db_password.txt
  • 64.
  • 65.
  • 66.
    @danaluther Inspect the containerfor the secret docker container inspect
  • 67.
    @danaluther Inspect the containerfor the secret docker container inspect > docker container inspect $(docker ps - lq - f name=test_db) > docker container inspect ff8dc39f919f > docker container inspect test_db.1.l8enz0qx7x8zci4156gh7i0qy
  • 68.
    @danaluther Inspect the containerfor the secret docker container inspect > docker container inspect kiskis_db_1 > docker container inspect 378020331e87 > docker container inspect $(docker ps - lq - f name=test_db) > docker container inspect ff8dc39f919f > docker container inspect test_db.1.l8enz0qx7x8zci4156gh7i0qy
  • 69.
    @danaluther Inspect the containerfor the secret docker container inspect
  • 70.
    @danaluther Inspect the containerfor the secret docker container inspect
  • 71.
    @danaluther Inspect the containerfor the secret docker container inspect
  • 72.
  • 73.
  • 74.
    @danaluther Can the containerchange the secret? Nope!!
  • 75.
    @danaluther Can *I* changethe secret? Yes, yes I can.
  • 76.
    @danaluther Can *I* changethe secret? Yes, yes I can. If I used docker stack deploy.
  • 77.
    @danaluther Updating a DockerSecret (Ok, you can’t actually update it, you have to replace it.) > docker secret create db_pwd.2 updatedcontent.txt
  • 78.
    @danaluther Updating a DockerSecret (Ok, you can’t actually update it, you have to replace it.) > docker service update - - secret - rm test_db_pwd - - secret - add src=db_pwd.2,target=db_pwd test_db
  • 79.
    @danaluther Confirm the update Updatingthe service launched a new container with a new secret. New: Original:
  • 80.
    @danaluther Great, but Idon’t care about the database… Right - lets put the secret to use in our DI container
  • 81.
    @danaluther Great, but Idon’t care about the database… Right - lets put the secret to use in our DI container
  • 82.
    @danaluther Sample API Objectv3 with $_ENV via DI Constructor moved to DI Container require 'vendor/autoload.php'; use YiisoftDiContainer; $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [$_ENV['MY_SECRET_KEY']] ], ]); $container - > get(ExampleSampleObjectConstructed : : class)
  • 83.
    @danaluther Sample API Objectv3 with $_ENV via DI Constructor moved to DI Container require 'vendor/autoload.php'; use YiisoftDiContainer; $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [$_ENV['MY_SECRET_KEY']] ], ]); $container - > get(ExampleSampleObjectConstructed : : class)
  • 84.
    @danaluther PHP stack withsecrets version: "3.7" services: php: image: php:8.1-rc - apache ports: - 8081 : 80 volumes: - ./src:/var/ w w w /html environment: - MY_SECRET_KEY=SomeKeyValue secrets: - hiddenkey - hiddenkey2 secrets: hiddenkey: file: ./secrets/secret - key - val.txt hiddenkey2 : file: ./secrets/secret - key - val2.txt
  • 85.
    @danaluther Deploy the Stackon a Swarm (Don’t need to init, just re-deploy for updates) > docker stack deploy - c docker - compose-8-1-nodb.yml test
  • 86.
    @danaluther Sample API Objectv3 with secret via DI Container populated from secret require 'vendor/autoload.php'; use YiisoftDiContainer; $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [file_get_contents('/run/secrets/hiddenkey')] ], ]);
  • 87.
    @danaluther Sample API Objectv3 with secret via DI Container populated from secret require 'vendor/autoload.php'; use YiisoftDiContainer; $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [file_get_contents('/run/secrets/hiddenkey')] ], ]); $container - > get(ExampleSampleObjectConstructed : : class)
  • 88.
    @danaluther Define multiple objectsin the container Multiple classes, multiple con fi gurations of one class $container = new Container([ ExampleSampleObjectConstructed : : class = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [file_get_contents('/run/secrets/hiddenkey')] ], ExamplePartnerConfigIdentifier : : OPT_CONFIG_1 = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > [file_get_contents('/run/secrets/hiddenkey2')] ], ExamplePartnerConfigIdentifier : : OPT_CONFIG_2 = > [ 'class' = > ExampleSampleObjectConstructed : : class, '__construct()' = > ['You can read me in the source repo.'] ], ]);
  • 89.
    @danaluther Using constants tokeep things tidy (Yes, it wants to be an enum, but we’re 7.4 compatible currently) class PartnerConfigIdentifier { public const DEFAULT_CONFIG = self : : class.':default'; public const OPT_CONFIG_1 = self : : class.':opt1'; public const OPT_CONFIG_2 = self : : class.':opt2'; public const OPT_CONFIG_3 = self : : class.':opt3'; }
  • 90.
    @danaluther Using constants tokeep things tidy (Yes, it wants to be an enum, but we’re 7.4 compatible currently) class PartnerConfigIdentifier { public const DEFAULT_CONFIG = self : : class.':default'; public const OPT_CONFIG_1 = self : : class.':opt1'; public const OPT_CONFIG_2 = self : : class.':opt2'; public const OPT_CONFIG_3 = self : : class.':opt3'; }
  • 91.
    @danaluther Create multiple objectsvia the container $container - > get(ExampleSampleObjectConstructed : : class); $container - > get(ExamplePartnerConfigIdentifier : : OPT_CONFIG_1); $container - > get(ExamplePartnerConfigIdentifier : : OPT_CONFIG_2);
  • 92.
    @danaluther Questions?? Ask now ortweet at me if you think of it later! https://www.linkedin.com/in/danaluther dluther@envisageinternational.com https://joind.in/talk/78c5b 🤔 ? ? ? ? https://github.com/DanaLuther/kiskis