Skip to content

Container lint command fails if referencing secrets not present in the environment  #35972

@spideyfusion

Description

@spideyfusion

Symfony version(s) affected: 4.4, 5.0

Description
If you reference a secret in your service configuration which is stored in a vault via the secrets:set command and you don't dump the secrets to your local environment with the secrets:decrypt-to-local command, running the container lint check with the lint:container command will result in a following exception:

In SodiumVault.php line 122:
                                                               
  [SodiumException]                                            
  keypair size should be SODIUM_CRYPTO_BOX_KEYPAIRBYTES bytes  
                                                               

Exception trace:
  at /bug/vendor/symfony/framework-bundle/Secrets/SodiumVault.php:122
 sodium_crypto_box_seal_open() at /bug/vendor/symfony/framework-bundle/Secrets/SodiumVault.php:122
 Symfony\Bundle\FrameworkBundle\Secrets\SodiumVault->reveal() at /bug/vendor/symfony/framework-bundle/Secrets/SodiumVault.php:166
 Symfony\Bundle\FrameworkBundle\Secrets\SodiumVault->list() at /bug/vendor/symfony/framework-bundle/Secrets/SodiumVault.php:174
 Symfony\Bundle\FrameworkBundle\Secrets\SodiumVault->loadEnvVars() at /bug/vendor/symfony/dependency-injection/EnvVarProcessor.php:153
 Symfony\Component\DependencyInjection\EnvVarProcessor->getEnv() at /bug/vendor/symfony/dependency-injection/Container.php:409
 Symfony\Component\DependencyInjection\Container->getEnv() at /bug/vendor/symfony/dependency-injection/ContainerBuilder.php:1522
 Symfony\Component\DependencyInjection\ContainerBuilder->getEnv() at /bug/vendor/symfony/dependency-injection/ContainerBuilder.php:1381
 Symfony\Component\DependencyInjection\ContainerBuilder->resolveEnvPlaceholders() at /bug/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php:204
 Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass->checkType() at /bug/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php:142
 Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass->checkTypeDeclarations() at /bug/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php:101
 Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass->processValue() at /bug/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php:81
 Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass->processValue() at /bug/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php:89
 Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass->processValue() at /bug/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php:46
 Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass->process() at /bug/vendor/symfony/dependency-injection/Compiler/Compiler.php:91
 Symfony\Component\DependencyInjection\Compiler\Compiler->compile() at /bug/vendor/symfony/dependency-injection/ContainerBuilder.php:734
 Symfony\Component\DependencyInjection\ContainerBuilder->compile() at /bug/vendor/symfony/framework-bundle/Command/ContainerLintCommand.php:67
 Symfony\Bundle\FrameworkBundle\Command\ContainerLintCommand->execute() at /bug/vendor/symfony/console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at /bug/vendor/symfony/console/Application.php:930
 Symfony\Component\Console\Application->doRunCommand() at /bug/vendor/symfony/framework-bundle/Console/Application.php:97
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /bug/vendor/symfony/console/Application.php:264
 Symfony\Component\Console\Application->doRun() at /bug/vendor/symfony/framework-bundle/Console/Application.php:83
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /bug/vendor/symfony/console/Application.php:140
 Symfony\Component\Console\Application->run() at /bug/bin/console:42

How to reproduce

NOTE: Native sodium PHP extension should be installed on your system.

  1. Create a new Symfony project (e.g. symfony new reproducer).

  2. Generate a new public/private key pair for the secrets vault with bin/console secrets:generate-keys.

  3. Add a secret to the vault with bin/console secrets:set TEST.

  4. Reference the secret in your service configuration:

App\Controller\TestController:
    arguments:
        - '%env(TEST)%'
  1. Run bin/console lint:container.

Possible Solution
We could just catch \Exception here instead, but I fear we would be potentially hiding a deeper issue.

Additional context
SodiumVault implements EnvVarLoaderInterface which gets triggered as a last fallback option when resolving environment variables (e.g. in CheckTypeDeclarationsPass, ResolveEnvPlaceholdersPass).

The problem is, SodiumVault provides a list of additional variables to be injected into the existing environment, but has an environment parameter as its own dependency. Seems like a chicken and egg situation to me.

This can only be reproduced if the container is compiled, but not dumped, which is why the lint:container command fails.

Workaround
You can disable the ability to pass the decryption key from an envirionment variable in your framework configuration:

framework:
    secrets:
        decryption_env_var: ~

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy