In modern application development, safeguarding sensitive information—like API keys, database credentials, and other secrets—is paramount. Storing such data directly in code or in unprotected Dataverse tables can lead to serious security risks, including accidental leaks and breaches. Years ago, I remember situations where we had to store these kind of informations in custom dataverse tables.
Fortunately, Power Platform Environment Variables provide a powerful way to decouple secrets and keys from the codebase, mitigating these risks. In this article, we’ll look at why environment variables are so crucial, outline their value, and dive into different types of environment variables and when to use them.
Why You Should Avoid Hardcoding Keys and Secrets
First of all, I would like to clarify the reasons why you should never keep your keys and code in the code. You might say to yourself, after all, my C# code is compiled as a DLL, ... but NO ! That is not enough to protect you.
1. Security Vulnerabilities: Keeping secrets in your code (or within a Dataverse table) can inadvertently expose them if the repository becomes public or if an unauthorized user gains read access.
2. Frequent Updates: API keys and credentials often need rotation or replacement. When they’re hardcoded, updating them across multiple files or tables is error-prone, time-consuming, and risky.
3. Team Collaboration Risks: With hardcoded secrets, every developer pulling your code automatically gains access to sensitive information, making it harder to enforce the principle of least privilege.
The Value of Environment Variables
Environment variables offer a clean way to inject sensitive or environment-specific data at runtime, ensuring secrets stay outside of the code repository. This feature was introduced in the Power Platform in 2020, and very well received by the community. Here’s why environment variables are so useful:
Environment variables isolate secret values from application code, simplifying deployments and updates. They make it easy to manage environment-specific configurations (development, test, production) without changing the code. Additionally, they facilitate maintenance by allowing credentials or secrets to be updated independently, while minimizing exposure of sensitive data by preventing it from appearing in Git or solution files.
Types of Environment Variables
While the term “environment variables” often gets used generically, there are various subtypes and different ways to handle them. Below are some common categories and scenarios:
1. Decimal number
stores decimal numbers in an environment.
Best Use : Used for environment-specific numeric configurations, such as thresholds or rates.
Considerations : Not sensitive, but should be protected from accidental changes.
2. JSON/YAML variables stores data in JSON format, useful for complex configurations.
Best Use : Ideal for managing hierarchical data structures and multi-level configuration settings.
Considerations : Can contain a lot of information, so ensure that the data is valid and well-formed.
3. Plain Text variables stores strings.
Best Use : Good for login names, service identifiers, or other non-sensitive text values.
Considerations : Good for human-readable data, but avoid storing secrets or passwords.
4. Yes/No Boolean variable to store true/false values.
Best Use : Used for feature flags or simple configuration options.
Considerations : Easy to manage, but keep clear documentation on the impact of each option.
5. Data source defines a data source for an application or service.
Best Use : Used to configure access to an external database or service.
Considerations : Ensure that access to sensitive sources is well protected.
6. Secure/Secret type variables are designed to store sensitive information such as passwords, API keys, authentication tokens, or certificates. They play a crucial role in securing applications by centralizing and encrypting critical data, reducing the risk of information leakage.
Best Use :
- Storage of login information (database passwords, SSH keys).
- API key management for third-party services.
- Storage of SSL certificates or JWT tokens.
- Centralization of secrets for multi-environment applications (dev, test, production).
Considerations : Encrypt and limit access to these variables. Ensure that they are not accessible in clear text in the logs.
Best Use : Used for environment-specific numeric configurations, such as thresholds or rates.
Considerations : Not sensitive, but should be protected from accidental changes.
2. JSON/YAML variables stores data in JSON format, useful for complex configurations.
Best Use : Ideal for managing hierarchical data structures and multi-level configuration settings.
Considerations : Can contain a lot of information, so ensure that the data is valid and well-formed.
3. Plain Text variables stores strings.
Best Use : Good for login names, service identifiers, or other non-sensitive text values.
Considerations : Good for human-readable data, but avoid storing secrets or passwords.
4. Yes/No Boolean variable to store true/false values.
Best Use : Used for feature flags or simple configuration options.
Considerations : Easy to manage, but keep clear documentation on the impact of each option.
5. Data source defines a data source for an application or service.
Best Use : Used to configure access to an external database or service.
Considerations : Ensure that access to sensitive sources is well protected.
6. Secure/Secret type variables are designed to store sensitive information such as passwords, API keys, authentication tokens, or certificates. They play a crucial role in securing applications by centralizing and encrypting critical data, reducing the risk of information leakage.
Best Use :
- Storage of login information (database passwords, SSH keys).
- API key management for third-party services.
- Storage of SSL certificates or JWT tokens.
- Centralization of secrets for multi-environment applications (dev, test, production).
Considerations : Encrypt and limit access to these variables. Ensure that they are not accessible in clear text in the logs.
Azure Key Vault
One of the best practices for managing secrets is to use Azure Key Vault, a cloud service designed to protect cryptographic keys and secrets used by applications. It allows you to centralize the management of secrets to avoid their dispersion in various configuration files, thus reducing the risk of sensitive information leakage. It may therefore be useful to store your "secret" type variables securely in Azure Key Vault.
Azure Key Vault automates key rotation and secret regeneration, thus strengthening security without manual intervention. It also offers fine-grained access control through defined policies and integrates seamlessly with Azure Active Directory (Azure AD) for optimized identity and permission management.
Azure Key Vault automates key rotation and secret regeneration, thus strengthening security without manual intervention. It also offers fine-grained access control through defined policies and integrates seamlessly with Azure Active Directory (Azure AD) for optimized identity and permission management.
Best Practices for Storing and Managing Environment Variables
1. Use Secure Storage Solutions: Services like Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault provide encryption and access control for your secrets.
2. Rotate Credentials Regularly: Reduce the blast radius of compromised credentials by updating them on a schedule.
3. Limit Access: Only the systems or team members that truly need these variables should have the permissions to view or modify them. Use the security model to the best implementation depending on your use case.
4. Avoid Logging Secrets: Be mindful of logs. Logging environment variable values can expose them, so mask or redact them if necessary.
5. Document Your Variables: Maintain a reference of all environment variables, their usage, and their default values. This helps onboarding new teammates and prevents confusion.
Conclusion
Moving your secrets out of code and into environment variables is a fundamental step toward bolstering security. By carefully choosing the appropriate type of environment variable—plain text, secure secret, JSON, Power Platform environment variables, or runtime session variables—you ensure that credentials, keys, and configurations are handled in the safest and most efficient way. Ultimately, the strategic use of environment variables streamlines your deployments, mitigates risk, and empowers your teams to manage configuration changes confidently, whether you’re working in Dataverse, Azure, or another platform in your tech stack.