Skip to main content
The Application SDK Framework provides built-in support for retrieving credentials from external secret stores, enabling secure credential management for your applications.
When building apps with the SDK, you can offer users the option to securely store and retrieve database credentials from supported secret management services instead of entering them directly.

Why Use Secret Stores?

Using secret stores offers several important advantages:

Enhanced Security

Credentials are stored and managed in a specialized secure service with encryption at rest and in transit.

Centralized Management

Credentials can be rotated and updated in one place without modifying application code.

Access Control

Secret stores provide fine-grained access controls and comprehensive audit logging.

Compliance

Help meet regulatory requirements for credential management and data security.

Supported Secret Stores

The Application SDK Framework currently supports:

AWS Secrets Manager

AWS Secrets Manager

A secure service that helps store, retrieve, and rotate database credentials, API keys, and other secrets throughout their lifecycle.
Support for additional secret stores can be added by implementing the CredentialProvider interface.

Implementation Guide

For App Developers

If you’re developing an app using the Application SDK Framework, follow these steps to integrate secret store support:
1

Add Credential Source Selection

Include a dropdown or similar control that allows users to select where their credentials are stored:
<div class="form-group">
  <label>Where are your credentials stored? *</label>
  <select id="credentialSource" onchange="handleCredentialSourceChange()">
    <option value="direct">I will enter them below</option>
    <option value="aws-secrets">AWS Secrets Manager</option>
  </select>
</div>
2

Collect Secret Store Metadata

Add form fields to collect necessary metadata based on the selected secret store:
<!-- AWS Secrets Manager Section (hidden by default) -->
<div id="aws-secrets-section" style="display: none;">
  <div class="form-group">
    <label>AWS Secret ARN *</label>
    <input 
      type="text" 
      id="aws-secret-arn" 
      placeholder="arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret-AbCdEf" 
    />
  </div>
  <div class="form-group">
    <label>AWS Region *</label>
    <input 
      type="text" 
      id="aws-secret-region" 
      placeholder="us-east-1" 
    />
  </div>
</div>
3

Handle Credential Resolution

The framework automatically resolves credentials based on the source selected:
from application_sdk.clients.credentials import resolve_credentials

# The framework handles resolution automatically
workflow_args = {
    "credentials": {
        "source": "aws-secrets",
        "secret_arn": user_input["aws_secret_arn"],
        "region": user_input["aws_region"],
        # Reference keys from the secret
        "username": "db_username",  # Key name in secret
        "password": "db_password",  # Key name in secret
        "host": "db_host",
        "port": "db_port",
        "database": "db_name",
    }
}
4

Provide User Guidance

Include documentation about how to format and enter credential references in your app’s help section or UI tooltips.

JavaScript Example

Here’s a complete example of handling credential source changes in your UI:
function handleCredentialSourceChange() {
  const source = document.getElementById('credentialSource').value;
  const awsSection = document.getElementById('aws-secrets-section');
  const directCredentialsSection = document.getElementById('direct-credentials-section');
  
  if (source === 'aws-secrets') {
    awsSection.style.display = 'block';
    directCredentialsSection.style.display = 'none';
  } else {
    awsSection.style.display = 'none';
    directCredentialsSection.style.display = 'block';
  }
}

function collectCredentials() {
  const source = document.getElementById('credentialSource').value;
  
  if (source === 'aws-secrets') {
    return {
      source: 'aws-secrets',
      secret_arn: document.getElementById('aws-secret-arn').value,
      region: document.getElementById('aws-secret-region').value,
      // Key references (not actual values)
      username: 'db_username',
      password: 'db_password',
      host: 'db_host',
      port: 'db_port',
      database: 'db_name',
    };
  } else {
    return {
      source: 'direct',
      username: document.getElementById('username').value,
      password: document.getElementById('password').value,
      host: document.getElementById('host').value,
      port: document.getElementById('port').value,
      database: document.getElementById('database').value,
    };
  }
}

AWS Secrets Manager Guide

For End Users

End users of your application can set up their credentials in AWS Secrets Manager by following these steps:
1

Log in to AWS Console

Navigate to the AWS Management Console and open the AWS Secrets Manager service.
2

Create a New Secret

  1. Click “Store a new secret”
  2. Select “Other type of secret”
  3. Enter credentials as key-value pairs
3

Add Credential Keys

Depending on your authentication type, add the appropriate keys:
4

Configure Secret Settings

  • Give the secret a descriptive name (e.g., “my-postgres-connection”)
  • Optionally configure automatic rotation settings
  • Add tags for organization
5

Copy Secret Details

Once created, copy:
  • The Secret ARN (e.g., arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret-AbCdEf)
  • The AWS region where the secret is stored

Authentication Types

For basic username/password authentication:
{
  "username": "postgres_user",
  "password": "secure_password_123"
}
Required keys:
  • username: Database username
  • password: Database password

Using Credentials in Your App

When users set up a connection in your app:
1

Select AWS Secrets Manager

Choose AWS Secrets Manager as the credential source.
2

Enter Secret Details

Provide the Secret ARN and AWS Region.
3

Reference Key Names

Instead of entering actual credentials, enter the key names from the secret:
  • If the secret contains a key named postgres_password, enter postgres_password in the Password field
  • The framework will automatically retrieve the actual value from AWS Secrets Manager
4

Test Connection

The application will fetch the actual credentials and test the connection.
The framework automatically retrieves and substitutes the actual values from AWS Secrets Manager at runtime.

Troubleshooting

If your connection fails when using AWS Secrets Manager:
  • Verify Secret ARN: Ensure the ARN is correct and the secret exists
  • Check Region: Confirm the AWS region is correctly specified
  • Validate Key Names: Ensure key names in the form exactly match the keys in the AWS secret
  • Check IAM Permissions: Verify the platform/environment has appropriate IAM permissions:
    • secretsmanager:GetSecretValue
    • secretsmanager:DescribeSecret
  • Review CloudTrail: Check AWS CloudTrail logs for access denied errors
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:*"
    }
  ]
}
If credentials are retrieved but connection still fails:
  • Check Secret Contents: Ensure the secret contains all required credential fields
  • Verify Values: Confirm credential values in the secret store are correct and up-to-date
  • Test Direct Connection: Try connecting with the credentials directly to isolate the issue
  • Check Credential Rotation: If using automatic rotation, ensure the credentials haven’t been rotated mid-connection
If you see permission denied errors:
  • IAM Role: Verify the IAM role attached to the application has the necessary permissions
  • Resource Policy: Check if the secret has a resource policy that restricts access
  • Service Control Policies: Ensure no SCPs are blocking Secrets Manager access
  • Cross-Account Access: If accessing secrets from another account, verify trust relationships
If the secret cannot be found:
  • ARN Format: Verify the ARN format is correct
  • Region Mismatch: Ensure you’re looking in the correct AWS region
  • Secret Deletion: Check if the secret was deleted (secrets have a recovery window)
  • Account Access: Confirm you’re accessing the correct AWS account

Technical Details

Credential Resolution Process

The credential resolution follows these steps:
1

Collect User Input

The application UI collects credential information including the source type and necessary metadata.
2

Select Provider

Based on the credential source, the appropriate credential provider is selected from the factory.
3

Extract Metadata

For secret store providers, necessary metadata (ARN, region, etc.) is extracted from the credential object.
4

Retrieve Credentials

The provider connects to the secret store service and retrieves the actual credentials:
from application_sdk.clients.credentials import CredentialProvider

class AWSSecretsManagerProvider(CredentialProvider):
    async def resolve(self, credentials: dict) -> dict:
        # Extract metadata
        secret_arn = credentials.get('secret_arn')
        region = credentials.get('region')
        
        # Retrieve from AWS Secrets Manager
        secret_value = await self.get_secret(secret_arn, region)
        
        # Substitute key references with actual values
        resolved = {}
        for key, ref in credentials.items():
            if key in ['secret_arn', 'region', 'source']:
                continue
            resolved[key] = secret_value.get(ref, ref)
        
        return resolved
5

Substitute Values

Retrieved values are substituted for key references in the original credential object.
6

Use Credentials

The resolved credentials are used for the database connection.

Extending Support

To add support for additional secret stores:
from application_sdk.clients.credentials import CredentialProvider

class CustomSecretStoreProvider(CredentialProvider):
    """Custom secret store provider implementation."""
    
    async def resolve(self, credentials: dict) -> dict:
        """Resolve credentials from custom secret store."""
        # 1. Extract metadata
        vault_url = credentials.get('vault_url')
        secret_path = credentials.get('secret_path')
        
        # 2. Connect to secret store
        client = await self.connect_to_vault(vault_url)
        
        # 3. Retrieve secret
        secret = await client.get_secret(secret_path)
        
        # 4. Map to credential format
        return {
            'username': secret['username'],
            'password': secret['password'],
            'host': secret['host'],
            'port': secret['port'],
            'database': secret['database'],
        }
    
    async def connect_to_vault(self, vault_url: str):
        """Connect to the secret store."""
        # Implementation specific to your secret store
        pass

# Register with factory
from application_sdk.clients.credentials import CredentialProviderFactory

CredentialProviderFactory.register('custom-vault', CustomSecretStoreProvider)
Implement the CredentialProvider interface and register with the CredentialProviderFactory to add support for new secret stores.

Security Best Practices

Least Privilege

Grant only the minimum necessary permissions to access secrets. Use specific resource ARNs instead of wildcards.

Enable Encryption

Use AWS KMS encryption for secrets at rest with customer-managed keys when possible.

Audit Access

Enable AWS CloudTrail logging to track all secret access and modifications.

Rotate Regularly

Implement automatic credential rotation to minimize the impact of credential compromise.

Use VPC Endpoints

Access Secrets Manager through VPC endpoints to avoid internet exposure.

Tag Secrets

Use tags to organize secrets and implement tag-based access control policies.

Next Steps

SQL Applications

Build SQL applications with secure credential management.

Best Practices

Follow best practices for application security and reliability.

AWS Secrets Manager

Learn more about AWS Secrets Manager features and capabilities.

Configuration

Configure your application with environment variables and settings.

Build docs developers (and LLMs) love