8000 Restrict secrets management to sodium+filesystem · symfony/symfony@78af50f · GitHub
[go: up one dir, main page]

Skip to content

Commit 78af50f

Browse files
Restrict secrets management to sodium+filesystem
1 parent 02b5d74 commit 78af50f

33 files changed

+867
-938
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ install:
207207
208208
if [[ ! $deps ]]; then
209209
php .github/build-packages.php HEAD^ src/Symfony/Bridge/PhpUnit src/Symfony/Contracts
210+
composer remove --dev --no-update paragonie/sodium_compat
210211
else
211212
export SYMFONY_DEPRECATIONS_HELPER=weak &&
212213
cp composer.json composer.json.orig &&

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
"monolog/monolog": "^1.25.1",
114114
"nyholm/psr7": "^1.0",
115115
"ocramius/proxy-manager": "^2.1",
116+
"paragonie/sodium_compat": "^1.8",
116117
"php-http/httplug": "^1.0|^2.0",
117118
"predis/predis": "~1.1",
118119
"psr/http-client": "^1.0",

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ CHANGELOG
1717
* Added new `error_controller` configuration to handle system exceptions
1818
* Added sort option for `translation:update` command.
1919
* [BC Break] The `framework.messenger.routing.senders` config key is not deep merged anymore.
20-
* Added secrets management.
20+
* Added `secrets:*` commands and `%env(secret:...)%` processor to deal with secrets seamlessly.
2121

2222
4.3.0
2323
-----

src/Symfony/Bundle/FrameworkBundle/Command/SecretsAddCommand.php

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/Symfony/Bundle/FrameworkBundle/Command/SecretsGenerateKeyCommand.php

Lines changed: 0 additions & 97 deletions
This file was deleted.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Command;
13+
14+
use Symfony\Bundle\FrameworkBundle\Secrets\AbstractVault;
15+
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Symfony\Component\Console\Output\ConsoleOutputInterface;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Symfony\Component\Console\Style\SymfonyStyle;
21+
22+
/**
23+
* @author Tobias Schultze <http://tobion.de>
24+
* @author Jérémy Derussé <jeremy@derusse.com>
25+
* @author Nicolas Grekas <p@tchwork.com>
26+
*/
27+
final class SecretsGenerateKeysCommand extends Command
28+
{
29+
protected static $defaultName = 'secrets:generate-keys';
30+
31+
private $vault;
32+
private $localVault;
33+
34+
public function __construct(AbstractVault $vault, AbstractVault $localVault = null)
35+
{
36+
$this->vault = $vault;
37+
$this->localVault = $localVault;
38+
39+
parent::__construct();
40+
}
41+
42+
protected function configure()
43+
{
44+
$this
45+
->setDescription('Generates new encryption keys.')
46+
->addOption('local', 'l', InputOption::VALUE_NONE, 'Updates the local vault.')
47+
->addOption('rotate', 'r', InputOption::VALUE_NONE, 'Re-encrypts existing secrets with the newly generated keys.')
48+
->setHelp(<<<'EOF'
49+
The <info>%command.name%</info> command generates a new encryption key.
50+
51+
<info>%command.full_name%</info>
52+
53+
If encryption keys already exist, the command must be called with
54+
the <info>--rotate</info> option in order to override those keys and re-encrypt
55+
existing secrets.
56+
57+
<info>%command.full_name% --rotate</info>
58+
EOF
59+
)
60+
;
61+
}
62+
63+
protected function execute(InputInterface $input, OutputInterface $output): int
64+
{
65+
$io = new SymfonyStyle($input, $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output);
66+
$vault = $input->getOption('local') ? $this->localVault : $this->vault;
67+
68+
if (null === $vault) {
69+
$io->success('The local vault is disabled.');
70+
71+
return 1;
72+
}
73+
74+
if (!$input->getOption('rotate')) {
75+
if ($vault->generateKeys()) {
76+
$io->success($vault->getLastMessage());
77+
78+
if ($this->vault === $vault) {
79+
$io->caution('DO NOT COMMIT THE DECRYPTION KEY FOR THE PROD ENVIRONMENT⚠️');
80+
}
81+
82+
return 0;
83+
}
84+
85+
$io->warning($vault->getLastMessage());
86+
87+
return 1;
88+
}
89+
90+
$secrets = [];
91+
foreach ($vault->list(true) as $name => $value) {
92+
if (null === $value) {
93+
$io->error($vault->getLastMessage());
94+
95+
return 1;
96+
}
97+
98+
$secrets[$name] = $value;
99+
}
100+
101+
if (!$vault->generateKeys(true)) {
102+
$io->warning($vault->getLastMessage());
103+
104+
return 1;
105+
}
106+
107+
$io->success($vault->getLastMessage());
108+
109+
if ($secrets) {
110+
foreach ($secrets as $name => $value) {
111+
$vault->seal($name, $value);
112+
}
113+
114+
$io->comment('Existing secrets have been rotated to the new keys.');
115+
}
116+
117+
if ($this->vault === $vault) {
118+
$io->caution('DO NOT COMMIT THE DECRYPTION KEY FOR THE PROD ENVIRONMENT⚠️');
119+
}
120+
121+
return 0;
122+
}
123+
}

0 commit comments

Comments
 (0)
0