How to use AWS Secrets Manager with PHP Code Examples – PHP Env 101

Use AWS Secrets Manager with PHP Code Examples

Here’s a step-by-step overview of how to use AWS secrets manager with PHP

  1. Create an AWS account.
  2. Install AWS SDK for PHP.
  3. Create a SecretsManagerClient object.
  4. Create a secrets vault using createSecret().
  5. Retrieve secrets from the vault using getSecretValue().
function getSecret($client, $secretId) {
    try {
        $result = $client ->getSecretValue([
            "SecretId" => $secretId
        ]);
        return $result;
    } catch(AwsException $e) {
        print_r('Error: ' . $e->getAwsErrorMessage());
    }
}

Dig Deeper into Managing Secrets & Environment Variables in PHP Applications

AWS Secrets Manager Article Assumptions

The article assumes the following.

  1. You have an AWS account and can log in to your console.
  2. You have installed SDK for PHP.

Keeping your Application’s Secrets safe in PHP with AWS Secrets Manager

Not good at keeping secrets?

When developing an application, you may need access to credentials or secrets like username, password, tokens, database connection strings, API, and access keys. Especially if you are trying to integrate third-party services, for instance – Authentication, email, or image hosting third-party services.

A novice developer may be tempted to hardcode them in the program itself. Now, if the developer pushes that program to a vault, he would give away those credentials to everyone who can access his code. Though it may be embarrassing for the developer, we all make mistakes, don’t we?

Avoid Prod .env file – ALWAYS! Use AWS Param Store or Secrets Manager for Environment Config in PHP Code

What most developers do is that they keep all these secrets and credentials in a .env file, usually in the root project directory. Almost every programming languages have functions to retrieve values from it in the runtime. Also, we don’t push the .env to a vault. The secrets stay in your local project directory.

AWS Secrets Manager with PHP
.env file example

The getenv() can access these environment variables in a PHP project.

<?php
getenv("FUELING_PHP_USERNAME"); //<username>
getenv("FUELING_PHP_PASSWORD"); //<password>
getenv("FUELING_PHP_AUTH_TOKEN"); //<auth-token>
?>

Going above & beyond

The magnitude of the environment variables tend to increase as the application scales up. An enterprise application can have hundreds of them. On top of that, each environment has its .env file – production, development, and testing are commonplace. Some may have more than just three of these environments.

So, updating and maintaining all those .env files can be challenging and error-prone. Credential rotation is usually a pain when you’re doing things manually. Rotation is when you change secrets and credentials after regular intervals for enhanced security. That’s where a more managed and automated service can help out. 

AWS Secrets Manager is one of the choices out there. Let’s learn more about it.

What is AWS Secrets Manager?

AWS Secrets Manager is a service for centrally managing the lifecycle of secrets. It is beyond just a secret keeper as it features encryption, rotation and access control.

AWS API opens up ways to retrieve these secrets in your program and rotate them in the runtime.

On top of that, AWS IAM controls fine-grained access to the vault of the secrets so only authenticated users can access it.

AWS Secrets Manager
Courtesy: AWS

AWS offers a 30-day free trial to acquaint you with Secrets manager. After the 30-day trial period, AWS charges based on the number of secrets stored and the API calls. There are no upfront charges or long-term contracts. Learn more about the price plan.

Pros & Cons of using AWS Secrets Manager in PHP

ProsCons
Fully-managed service by AWS for storing secrets securely.Comparatively more expensive than similar services, including Hashipcorp’s Vault, AWS Parameter Store
Automatic password rotations with native support for AWS RDS.Password rotation involves lambda functions that could be complicated for those with little or no experience developing and testing lambdas.
Integrates well with other AWS services, including AWS Lambdas, CloudWatch, Cloudtrial and KMS.Vendor-lockin if not managed well.
Secrets could be replicated easily in different environments and regions.Overkill if you don’t need encryption key rotation
Encrypts secrets at rest using AWS KMS and uses TLS for secure transfer.
AWS Features versatile SDK API for programmatic use.
Uses IAM for fine-grained access control

Features of AWS Secrets Manager

Storing your secrets securely

AWS uses encryption at rest to encrypt the secrets. When you make a call, it decrypts and sends it over to you using TLS, the standard protocol for transferring data on the internet. So, you are much safer than hackers keen to sniff data packets and compromise software systems.

Another feature that adds to the security is using IAM with the Secrets manager. IAM defines access privileges for a user or group of users. So, unauthenticated users are always restricted from the vaults where you keep credentials and secrets.

Note: Using AWS KMS custom keys will add the current KMS rate to the base costs. Learn more about KMS pricing.

Featuring efficient programming APIs

AWS SDK offers APIs to communicate with services. You can programmatically retrieve the secrets using SDK’s Secret Manager API and schedule rotation right from your program.

Besides, you can also use the built-in client-side cache with the Secret Manager to reduce latency and costs. 

Rotating credentials without affecting your program

You can always perform a rotation on schedule or demand from the AWS console, SDK or CLI. The changes are reflected without breaking the application. A fantastic feature is that the secrets manager natively supports secrets rotation for managed services like AWS RDS. 

Note: Secrets Manager uses lambda functions to automate rotation. When you enable rotation, AWS will add the current lambda rate to the base cost. Learn more about lambda pricing.

Replicating your secrets

With AWS Secrets manager, you can easily replicate your secrets in multiple environments and regions. You no longer need to manually copy and paste hundreds of credentials because AWS automates the replication. You can also create read replicas of the primary secret vault, and AWS will keep them in sync.

Monitoring your secrets

You can keep track of your secrets with AWS monitoring and logging services. You can use Coudtrail logs to monitor when a secret is created and rotated. Similarly, AWS CloudWatch can help you receive notifications when some activity happens – for example, some secret rotates or remains unused for a long time.

Note: You should know the Cloudtrail pricing before using it with the Secrets manager to estimate your costs correctly.

Basic AWS Secrets Manager Example

The following illustration demonstrates the baseline use case.

Flow diagram

1. Users with the right permissions add secrets to a vault.

2. The application retrieves secrets using the vault name.

3. The application uses secrets to access the database.

Note that the application uses AWS SDK to interact with the Secrets manager. The article assumes you have installed AWS SDK and know the fundamentals at least.

Use AWS Secrets Manager via AWS Console.

Create a vault in the AWS secrets manager 

Sign In to the AWS console and navigate AWS Secrets Manager.

AWS Secrets Manager with PHP
AWS Secrets Manager

 In the Secrets Manager dashboard, click on Store a new secret.

AWS Secrets Manager
AWS Secrets Manager

In the Choose secret type, you can do the following.

  1. Select the type of secret, and choose the Other type of secret if native solutions are not what you’re looking for.
  2. Add secrets using Key/Value or Plain Text format. Prefer Key/Value if you are adding secrets manually. Click on Add row to keep on adding secrets.
  3. If you don’t want to use custom KMS keys, you can leave the Encryption key to the default aws/secretsmanager.

    Note: Using Custom KMS keys will incur additional charges per the AWS KMS pricing plan.
  4. Feel free to proceed by clicking the Next button.
AWS Secrets Manager with PHP
Choose secret type

In the Configure secret, you need to provide a secret name to reference the secrets later vault by this name in your programs. Optionally you can do the following.

  1. Provide a Description of the secrets vault.
  2. Add Tags relevant to the vault.
  3. Add access permissions using AWS JSON policies.
  4. Replicate the vault in another region for redundancy and recovery.

Feel free to proceed by clicking the Next button.

Configure secret
Configure secret

In the Configure rotation, you can optionally enable the auto-rotation option. We will keep it disabled for now and will proceed by clicking Next.

Note: Auto-rotation uses the lambda function, which would add to your costs as per the cost schedule.

AWS Secrets Manager with PHP
Configure rotation

Finally, review all the configurations and click Store

AWS also gives you these code snippets for different programming languages that you can use to retrieve the secrets programmatically. Unfortunately, PHP is not there but don’t worry. We will work on that later.

AWS SDK code snippets
AWS SDK code snippets

Voila! The vault has been created in the secrets manager.

 AWS Secrets Manager with PHP
AWS Secrets vault

Retrieve secrets from the vault

The goal is to retrieve the secrets programmatically. Before that, we will see how to reveal them in the console. 

Note: You need the right permissions to access the vault in the secrets manager.

Navigate to the vault and click the Retrieve secret value button in the Secret value.

tutorial/fuelingphp
tutorial/fuelingphp

That will show all the secrets that are in the vault.

AWS Secrets Manager with PHP
Secrets

Add, edit and remove secrets from the vault

In the Secret value, click Edit.

Edit vault
Edit vault

That opens up a menu where you can intuitively add, remove or edit existing secrets.

AWS Secrets Manager with PHP
Edit secrets

Next, let’s see how to use AWS secrets manager with PHP.

Use AWS Secrets Manager with PHP Code via AWS SDK Example.

Create SecretsManagerClient in PHP Code

AWS SDK features the SecretsManagerClient object, which is an API to interact with the AWS Secrets manager using PHP.

<?php
require "vendor/autoload.php";
 
use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
 
$secretManagerClient = new SecretsManagerClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => "latest"
]);
?>

The SecretsManagerClient expects an AWS profile with valid permissions. We pass the default profile that has been a while ago. Creating an AWS profile for programmatic access is out of the scope of this tutorial, but you can learn how to create one here.

Create a vault in AWS secrets manager with PHP.

Let’s create a new vault via PHP with the name “tutorialv2/fuelingphp”.

The SecretsManagerClient object features createSecret() that will help us create a vault. It expects pretty much the same arguments as we have seen while creating a vault in the console. We will provide name, description and JSON specifying secrets.

function createSecret($client, $configArray) {
    try {
        $result = $client->createSecret([
            "Name" => isset($configArray["Name"]) ?  $configArray["Description"] : "Default",
            "Description" => isset($configArray["Description"]) ? $configArray["Description"] : "No description",
            "SecretString" => isset($configArray["SecretsString"]) ? $configArray["SecretsString"] : "{:}"
        ]);
        return $result;
    } catch(AwsException $e) {
        print_r('Error: ' . $e->getAwsErrorMessage());
    }
}

Calling this function creates a new vault and returns an object with a bunch of information, including the ARN, a version ID and the vault’s name.

Retrieve AWS secrets from the secrets manager with PHP Example

We have created a wrapper function that expects a SecretsManagerClient object and a secretId string. It calls the getSecretValue() method on the client object.

A SecretID, which could be the vault’s name or ARN. We have provided the name “tutorialv2/fuelingphp”.

function getSecret($client, $secretId) {
    try {
        $result = $client ->getSecretValue([
            "SecretId" => $secretId
        ]);
        return $result;
    } catch(AwsException $e) {
        print_r('Error: ' . $e->getAwsErrorMessage());
    }
}

This method returns a response object if everything goes well.

$secrets = getSecret($secretManagerClient, "tutorialv2/fuelingphp");

The object has all the necessary information, but the secrets are grouped in the “SecretsString” key.

json_decode($secrets["SecretString"]);
 
/*
stdClass Object
(
    [fuelingphp_email] => dummyemail
    [fuelingphp_password] => dummypassword
)
*/

Voila! It is that simple. We no longer rely on a local .env file but on a central vault hosted in the AWS cloud.

That’s not all. You can see the full list of methods in the secrets manager API.

Using AWS Secrets Manager in PHP

This article demonstrates how to use AWS secrets manager with PHP. AWS features an SDK that opens up a bunch of APIs to communicate with their services. A client program can use Secrets manager API to create a client object and a vault and retrieve secrets from it. All of it can be done by calling different methods on the client object.

The article also uses the AWS console to create a vault and put secrets in it so that users who prefer a more GUI-based approach can easily find their way through this service. Apart from that, the article opens up with some insights about the AWS secrets manager itself, including its pricing model, features, pros, and cons.

Hope you’ve liked this article. Stay tuned for more at FuelingPHP.

Get deeper with PHP

We have many fun articles related to PHP. You can explore these to learn more about PHP.


© 2022 Confident.Systems