You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a developer, I'd like to have all values that contain secrets protected, in order to improve security when generating manifests.
The implementation right now uses the ISecretProtectionStrategy and the BaseResourceProcessor.GetSecretEnvironmentalVariables() to decide whether the environment variables contain a secret value that needs to be protected. That decision is done by checking if the environment variable names start with any of the values predefined in the ProtectorType SmartEnum. This means that:
Aspirate needs to have a Protector implementation for every kind of resource that the developers want to use (think here rabbitmq, qdrant, {insert custom service that needs a secret env variable}). As long as there isn't one for a certain resource, then that resource cannot be used in the Aspire orchestration and have properly generated secrets in manifests.
There is no way for the developer to use other resources than the ones supported (those that use ConnectionString_* env variable names, MSSQL, or Postgres) or create their own custom resources (that need env variables with arbitrary names that have a secret value).
For example, when trying to add a RabbitMQ Service to the orchestration using builder.AddRabbitMQ("RabbitMQService") the resulting Helm Chart for the service will have a rabbitmqservice-configmap.yaml like the one below and no rabbitmqservice-secret.yaml will be generated. Note that the password for the admin user of the RabbitMQ instance is in plain text.
A generic solution for this problem would be to rely on the ParameterResource.Inputs[*].Secret boolean property. As in the example, we could assume that most of the time any value that needs to have its value kept secret is being computed from a ParameterResource that is marked as Secret. A few examples:
RabbitMQService.env.RABBITMQ_DEFAULT_PASS will have to substitute the value of the RabbitMQService-password Secure Parameter to compute its value, which makes it Secure as well.
example-project.env.ConnectionStrings__RabbitMQService will have its "{RabbitMQService.connectionString}" value substituted to "amqp://guest:{RabbitMQService-password.value}@{RabbitMQService.bindings.tcp.host}:{RabbitMQService.bindings.tcp.port}" which in turn will have to use the value of RabbitMQService-password.value to finish the substitution, which will make both values in the chain be considered Secure as well. (so the lookup will have to be done recursively)
With this in mind we can derive the secretness of the values when we do the substitutions in SubstituteValuesAspireManifestAction and create some sort of SecretsMap that tells us which of the substituted values are secret. Then, every time we need to decide whether a value needs to be part of the manifest/configmap or the secrets we check against this SecretsMap instead of relying on the fixed ProtectorType SmartEnum.
I created a very rough POC here to exemplify this potential solution. I've also created a small UnitTest to be able to quickly run this scenario and prove that the resulting manifest has all its secrets put in the proper place. I am not very familiar with the codebase and did not know exactly where the implementation should be, so I tried to make minimal changes and avoid changing APIs/models as much as possible (especially the *Resource classes).
🚧 Blocked by
nothing I am aware of
The text was updated successfully, but these errors were encountered:
🚀 Feature Description
As a developer, I'd like to have all values that contain secrets protected, in order to improve security when generating manifests.
The implementation right now uses the
ISecretProtectionStrategy
and theBaseResourceProcessor.GetSecretEnvironmentalVariables()
to decide whether the environment variables contain a secret value that needs to be protected. That decision is done by checking if the environment variable names start with any of the values predefined in theProtectorType
SmartEnum. This means that:ConnectionString_*
env variable names, MSSQL, or Postgres) or create their own custom resources (that need env variables with arbitrary names that have a secret value).For example, when trying to add a RabbitMQ Service to the orchestration using
builder.AddRabbitMQ("RabbitMQService")
the resulting Helm Chart for the service will have a rabbitmqservice-configmap.yaml like the one below and no rabbitmqservice-secret.yaml will be generated. Note that the password for the admin user of the RabbitMQ instance is in plain text.🧰 Possible Solution
Let's start with an example manifest.json
A generic solution for this problem would be to rely on the
ParameterResource.Inputs[*].Secret
boolean property. As in the example, we could assume that most of the time any value that needs to have its value kept secret is being computed from a ParameterResource that is marked as Secret. A few examples:RabbitMQService.env.RABBITMQ_DEFAULT_PASS
will have to substitute the value of theRabbitMQService-password
Secure Parameter to compute its value, which makes it Secure as well.example-project.env.ConnectionStrings__RabbitMQService
will have its"{RabbitMQService.connectionString}"
value substituted to"amqp://guest:{RabbitMQService-password.value}@{RabbitMQService.bindings.tcp.host}:{RabbitMQService.bindings.tcp.port}"
which in turn will have to use the value ofRabbitMQService-password.value
to finish the substitution, which will make both values in the chain be considered Secure as well. (so the lookup will have to be done recursively)With this in mind we can derive the secretness of the values when we do the substitutions in SubstituteValuesAspireManifestAction and create some sort of SecretsMap that tells us which of the substituted values are secret. Then, every time we need to decide whether a value needs to be part of the manifest/configmap or the secrets we check against this SecretsMap instead of relying on the fixed
ProtectorType
SmartEnum.I created a very rough POC here to exemplify this potential solution. I've also created a small UnitTest to be able to quickly run this scenario and prove that the resulting manifest has all its secrets put in the proper place. I am not very familiar with the codebase and did not know exactly where the implementation should be, so I tried to make minimal changes and avoid changing APIs/models as much as possible (especially the
*Resource
classes).🚧 Blocked by
The text was updated successfully, but these errors were encountered: