or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cognito-credentials.mdconfiguration-file-credentials.mdcustom-credential-chains.mddefault-provider-chain.mdenvironment-credentials.mdhttp-credentials.mdindex.mdmetadata-service-credentials.mdprocess-credentials.mdsso-credentials.mdtemporary-credentials.mdweb-identity-credentials.md
tile.json

process-credentials.mddocs/

External Process Credentials

External process credential provider executes external processes and parses their JSON output to retrieve credentials, useful for integration with custom credential management systems and corporate authentication tools.

Capabilities

Process Credential Provider

Executes external processes to retrieve AWS credentials.

/**
 * Creates a credential provider function that executes external process and parses JSON output
 * @param init - Process credential configuration parameters
 * @returns Process credential provider function
 */
function fromProcess(init?: FromProcessInit): AwsCredentialIdentityProvider;

interface FromProcessInit {
  /** Configuration profile name (defaults to AWS_PROFILE or 'default') */
  profile?: string;
  /** Path to shared credentials file (defaults to ~/.aws/credentials) */
  filepath?: string;
  /** Path to shared config file (defaults to ~/.aws/config) */
  configFilepath?: string;
}

Usage Examples:

import { S3Client } from "@aws-sdk/client-s3";
import { fromProcess } from "@aws-sdk/credential-providers";

// Use default profile process configuration
const client = new S3Client({
  region: "us-east-1",
  credentials: fromProcess()
});

// Use specific profile
const devClient = new S3Client({
  region: "us-east-1",
  credentials: fromProcess({
    profile: "development"
  })
});

// Custom configuration file paths
const customClient = new S3Client({
  region: "us-east-1",
  credentials: fromProcess({
    filepath: "/custom/path/credentials",
    configFilepath: "/custom/path/config"
  })
});

Configuration File Setup

Configure credential processes in AWS configuration files:

~/.aws/credentials:

[default]
credential_process = /usr/local/bin/aws-credentials

[development]
credential_process = /usr/local/bin/aws-credentials --environment dev

[production]
credential_process = /usr/local/bin/aws-credentials --environment prod --mfa

~/.aws/config:

[default]
credential_process = /usr/local/bin/aws-credentials
region = us-east-1

[profile development]
credential_process = /usr/local/bin/aws-credentials --environment dev
region = us-west-2

Expected Process Output

External processes must output JSON to stdout in this exact format:

{
  "Version": 1,
  "AccessKeyId": "ASIAIOSFODNN7EXAMPLE",
  "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "SessionToken": "AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5T...",
  "Expiration": "2023-12-31T23:59:59Z"
}

Example Credential Process Scripts

Basic Shell Script

#!/bin/bash
# /usr/local/bin/aws-credentials

# Example: retrieve credentials from corporate vault
VAULT_RESPONSE=$(vault kv get -format=json secret/aws/credentials)

# Extract credentials from vault response
ACCESS_KEY=$(echo "$VAULT_RESPONSE" | jq -r '.data.data.access_key')
SECRET_KEY=$(echo "$VAULT_RESPONSE" | jq -r '.data.data.secret_key')
SESSION_TOKEN=$(echo "$VAULT_RESPONSE" | jq -r '.data.data.session_token')
EXPIRATION=$(echo "$VAULT_RESPONSE" | jq -r '.data.data.expiration')

# Output in required format
cat <<EOF
{
  "Version": 1,
  "AccessKeyId": "$ACCESS_KEY",
  "SecretAccessKey": "$SECRET_KEY",
  "SessionToken": "$SESSION_TOKEN",
  "Expiration": "$EXPIRATION"
}
EOF

Python Script

#!/usr/bin/env python3
# /usr/local/bin/aws-credentials

import json
import sys
import boto3
import argparse
from datetime import datetime, timezone

def get_credentials(environment):
    """Retrieve credentials from custom source"""
    # Example: corporate SSO or identity provider integration
    
    if environment == "dev":
        # Development credentials logic
        return {
            "AccessKeyId": "AKIA...",
            "SecretAccessKey": "...",
            "SessionToken": "...",
            "Expiration": "2023-12-31T23:59:59Z"
        }
    elif environment == "prod":
        # Production credentials logic
        # Could integrate with HashiCorp Vault, Azure Key Vault, etc.
        return fetch_from_vault(environment)
    
    raise ValueError(f"Unknown environment: {environment}")

def fetch_from_vault(environment):
    """Example integration with external credential store"""
    # Your custom credential retrieval logic here
    pass

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--environment", default="default")
    parser.add_argument("--mfa", action="store_true")
    args = parser.parse_args()
    
    try:
        credentials = get_credentials(args.environment)
        output = {
            "Version": 1,
            **credentials
        }
        print(json.dumps(output))
    except Exception as e:
        print(json.dumps({"Error": str(e)}), file=sys.stderr)
        sys.exit(1)

Node.js Script

#!/usr/bin/env node
// /usr/local/bin/aws-credentials

const { execSync } = require('child_process');

async function getCredentials() {
  try {
    // Example: integrate with corporate identity system
    const response = await fetch('https://internal-auth.company.com/aws-credentials', {
      headers: {
        'Authorization': `Bearer ${process.env.COMPANY_TOKEN}`
      }
    });
    
    const data = await response.json();
    
    return {
      Version: 1,
      AccessKeyId: data.accessKey,
      SecretAccessKey: data.secretKey,
      SessionToken: data.sessionToken,
      Expiration: data.expiresAt
    };
  } catch (error) {
    console.error(JSON.stringify({ Error: error.message }));
    process.exit(1);
  }
}

getCredentials().then(credentials => {
  console.log(JSON.stringify(credentials));
});

Environment-Specific Processes

Handle different environments with parameters:

~/.aws/config:

[profile dev-vault]
credential_process = vault-aws-credentials --environment=development

[profile prod-vault]
credential_process = vault-aws-credentials --environment=production --require-mfa

[profile test-corp]
credential_process = corporate-sso-credentials --domain=test.company.com

MFA Integration

Implement MFA in credential processes:

#!/bin/bash
# MFA-enabled credential process

if [ "$1" = "--mfa" ]; then
    echo "Enter MFA token: " >&2
    read -s MFA_TOKEN
    VAULT_TOKEN=$(vault auth -method=aws -token="$MFA_TOKEN")
fi

# Retrieve credentials using MFA-authenticated session
vault kv get -format=json secret/aws/prod-credentials | \
  jq '{
    Version: 1,
    AccessKeyId: .data.data.access_key,
    SecretAccessKey: .data.data.secret_key,
    SessionToken: .data.data.session_token,
    Expiration: .data.data.expiration
  }'

Error Handling

Handle process credential failures:

import { fromProcess } from "@aws-sdk/credential-providers";

try {
  const credentials = await fromProcess({
    profile: "vault-profile"
  })();
} catch (error) {
  if (error.message.includes('Process exited with non-zero status')) {
    console.error('Credential process failed - check process configuration');
  } else if (error.message.includes('Invalid JSON response')) {
    console.error('Process output is not valid JSON');
  } else if (error.message.includes('Profile not found')) {
    console.error('Process profile does not exist in configuration');
  } else {
    console.error('Process credentials failed:', error.message);
  }
}

Security Considerations

Process Permissions

# Set secure permissions for credential processes
chmod 750 /usr/local/bin/aws-credentials
chown root:aws-users /usr/local/bin/aws-credentials

Environment Variables

# Avoid passing secrets as command line arguments
# Use environment variables or secure files instead
credential_process = aws-credentials # Good
credential_process = aws-credentials --secret=xyz123 # Bad - visible in process list

Logging and Monitoring

import logging
import json

# Log credential requests for auditing
logging.basicConfig(
    filename='/var/log/aws-credentials.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def get_credentials(environment):
    logging.info(f"Credential request for environment: {environment}")
    # ... credential retrieval logic
    logging.info("Credentials retrieved successfully")
    return credentials

Integration Examples

HashiCorp Vault

#!/bin/bash
# Vault AWS secrets engine integration

vault write aws/sts/developer ttl=1h | \
  jq '{
    Version: 1,
    AccessKeyId: .data.access_key,
    SecretAccessKey: .data.secret_key,
    SessionToken: .data.security_token,
    Expiration: (.data.ttl | tostring + "s" | now + (tonumber | floor) | strftime("%Y-%m-%dT%H:%M:%SZ"))
  }'

AWS SSO with Custom Logic

#!/usr/bin/env python3
import boto3
import json
from datetime import datetime, timezone

def get_sso_credentials():
    """Custom SSO credential logic"""
    sso_client = boto3.client('sso')
    
    # Custom SSO logic here
    response = sso_client.get_role_credentials(
        roleName='MyRole',
        accountId='123456789012',
        accessToken=get_cached_sso_token()
    )
    
    credentials = response['roleCredentials']
    return {
        "Version": 1,
        "AccessKeyId": credentials['accessKeyId'],
        "SecretAccessKey": credentials['secretAccessKey'],
        "SessionToken": credentials['sessionToken'],
        "Expiration": datetime.fromtimestamp(
            credentials['expiration'] / 1000, timezone.utc
        ).isoformat().replace('+00:00', 'Z')
    }

print(json.dumps(get_sso_credentials()))

Performance Optimization

Process credentials are executed on each request:

#!/bin/bash
# Add caching to reduce external calls

CACHE_FILE="/tmp/aws-credentials-cache-$(id -u)"
CACHE_DURATION=3300 # 55 minutes

if [ -f "$CACHE_FILE" ] && [ $(($(date +%s) - $(stat -c %Y "$CACHE_FILE"))) -lt $CACHE_DURATION ]; then
    cat "$CACHE_FILE"
else
    # Fetch new credentials
    NEW_CREDS=$(vault kv get -format=json secret/aws/credentials | \
      jq '{Version:1,AccessKeyId:.data.data.access_key,SecretAccessKey:.data.data.secret_key,SessionToken:.data.data.session_token,Expiration:.data.data.expiration}')
    
    echo "$NEW_CREDS" | tee "$CACHE_FILE"
fi

Availability

  • Node.js: ✅ Available
  • Browser: ❌ Not available (cannot execute processes)
  • React Native: ❌ Not available