CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-amazonaws--aws-java-sdk-secretsmanager

Java client library for AWS Secrets Manager enabling secure storage, management, and retrieval of secrets.

Pending
Overview
Eval results
Files

utilities.mddocs/

Utility Operations

Helper functions for enhanced security and compliance including secure random password generation and resource policy validation.

Random Password Generation

The AWS Secrets Manager service provides a secure random password generator that can create passwords meeting specific complexity requirements. This is useful for automated password rotation and initial secret creation.

GetRandomPasswordRequest

class GetRandomPasswordRequest extends AmazonWebServiceRequest {
    Long passwordLength;                      // Password length (4-4096, default: 32)
    String excludeCharacters;                 // Characters to exclude
    Boolean excludeNumbers;                   // Exclude numeric characters (0-9)
    Boolean excludePunctuation;               // Exclude punctuation (!@#$%^&*()_+-=[]{}|;:,.<>?)
    Boolean excludeUppercase;                 // Exclude uppercase letters (A-Z)
    Boolean excludeLowercase;                 // Exclude lowercase letters (a-z)
    Boolean includeSpace;                     // Include space character
    Boolean requireEachIncludedType;          // Require at least one character from each enabled type
}

GetRandomPasswordResult

class GetRandomPasswordResult {
    String randomPassword;                    // Generated password
}

Basic Password Generation

// Generate a basic 32-character password
GetRandomPasswordRequest basicRequest = new GetRandomPasswordRequest();

GetRandomPasswordResult basicResult = client.getRandomPassword(basicRequest);
String basicPassword = basicResult.getRandomPassword();
System.out.println("Generated password: " + basicPassword);

// Generate a 16-character password
GetRandomPasswordRequest shortRequest = new GetRandomPasswordRequest()
    .withPasswordLength(16L);

GetRandomPasswordResult shortResult = client.getRandomPassword(shortRequest);
String shortPassword = shortResult.getRandomPassword();

Custom Password Requirements

// Generate password without special characters
GetRandomPasswordRequest alphanumericRequest = new GetRandomPasswordRequest()
    .withPasswordLength(20L)
    .withExcludePunctuation(true)
    .withRequireEachIncludedType(true);

GetRandomPasswordResult alphanumericResult = client.getRandomPassword(alphanumericRequest);
String alphanumericPassword = alphanumericResult.getRandomPassword();

// Generate password with specific exclusions
GetRandomPasswordRequest customRequest = new GetRandomPasswordRequest()
    .withPasswordLength(24L)
    .withExcludeCharacters("0O1lI")  // Exclude confusing characters
    .withRequireEachIncludedType(true);

GetRandomPasswordResult customResult = client.getRandomPassword(customRequest);
String customPassword = customResult.getRandomPassword();

// Generate a simple password (letters and numbers only)
GetRandomPasswordRequest simpleRequest = new GetRandomPasswordRequest()
    .withPasswordLength(12L)
    .withExcludePunctuation(true)
    .withRequireEachIncludedType(true);

GetRandomPasswordResult simpleResult = client.getRandomPassword(simpleRequest);
String simplePassword = simpleResult.getRandomPassword();

Advanced Password Generation

// Database-friendly password (no special chars that might cause issues)
GetRandomPasswordRequest dbFriendlyRequest = new GetRandomPasswordRequest()
    .withPasswordLength(32L)
    .withExcludePunctuation(true)
    .withExcludeCharacters("'\"\\`")  // Exclude SQL problematic characters
    .withRequireEachIncludedType(true);

GetRandomPasswordResult dbFriendlyResult = client.getRandomPassword(dbFriendlyRequest);

// URL-safe password (no characters that need URL encoding)
GetRandomPasswordRequest urlSafeRequest = new GetRandomPasswordRequest()
    .withPasswordLength(28L)
    .withExcludeCharacters("!@#$%^&*()+={}[]|\\:;\"'<>,.?/~`")
    .withRequireEachIncludedType(true);

GetRandomPasswordResult urlSafeResult = client.getRandomPassword(urlSafeRequest);

// High entropy password with all character types
GetRandomPasswordRequest highEntropyRequest = new GetRandomPasswordRequest()
    .withPasswordLength(40L)
    .withIncludeSpace(false)  // Avoid spaces for compatibility
    .withRequireEachIncludedType(true);

GetRandomPasswordResult highEntropyResult = client.getRandomPassword(highEntropyRequest);

Password Generation Patterns

public class PasswordGenerator {
    
    private final AWSSecretsManager client;
    
    public PasswordGenerator(AWSSecretsManager client) {
        this.client = client;
    }
    
    // Generate password for database users
    public String generateDatabasePassword() {
        GetRandomPasswordRequest request = new GetRandomPasswordRequest()
            .withPasswordLength(24L)
            .withExcludePunctuation(true)
            .withExcludeCharacters("'\"\\`")  // Avoid SQL injection issues
            .withRequireEachIncludedType(true);
        
        return client.getRandomPassword(request).getRandomPassword();
    }
    
    // Generate password for API keys (alphanumeric only)
    public String generateAPIPassword() {
        GetRandomPasswordRequest request = new GetRandomPasswordRequest()
            .withPasswordLength(32L)
            .withExcludePunctuation(true)
            .withRequireEachIncludedType(true);
        
        return client.getRandomPassword(request).getRandomPassword();
    }
    
    // Generate secure password with maximum entropy
    public String generateSecurePassword(int length) {
        GetRandomPasswordRequest request = new GetRandomPasswordRequest()
            .withPasswordLength((long) length)
            .withRequireEachIncludedType(true);
        
        return client.getRandomPassword(request).getRandomPassword();
    }
    
    // Generate password meeting corporate policy
    public String generateCorporatePassword() {
        GetRandomPasswordRequest request = new GetRandomPasswordRequest()
            .withPasswordLength(16L)
            .withRequireEachIncludedType(true)
            .withExcludeCharacters("0O1lI5S");  // Exclude confusing characters
        
        return client.getRandomPassword(request).getRandomPassword();
    }
    
    // Generate temporary password (shorter, alphanumeric)
    public String generateTemporaryPassword() {
        GetRandomPasswordRequest request = new GetRandomPasswordRequest()
            .withPasswordLength(8L)
            .withExcludePunctuation(true)
            .withExcludeCharacters("0O1lI")
            .withRequireEachIncludedType(true);
        
        return client.getRandomPassword(request).getRandomPassword();
    }
}

Automated Secret Creation with Generated Passwords

// Create secret with automatically generated password
public String createSecretWithGeneratedPassword(String secretName, 
                                               String description,
                                               int passwordLength) {
    try {
        // Generate secure password
        GetRandomPasswordRequest passwordRequest = new GetRandomPasswordRequest()
            .withPasswordLength((long) passwordLength)
            .withRequireEachIncludedType(true);
        
        GetRandomPasswordResult passwordResult = client.getRandomPassword(passwordRequest);
        String generatedPassword = passwordResult.getRandomPassword();
        
        // Create secret with generated password
        CreateSecretRequest createRequest = new CreateSecretRequest()
            .withName(secretName)
            .withSecretString(generatedPassword)
            .withDescription(description);
        
        CreateSecretResult createResult = client.createSecret(createRequest);
        
        System.out.println("Created secret: " + createResult.getName());
        System.out.println("Secret ARN: " + createResult.getArn());
        
        return generatedPassword;
        
    } catch (Exception e) {
        System.err.println("Failed to create secret with generated password: " + e.getMessage());
        throw e;
    }
}

// Usage
String password = createSecretWithGeneratedPassword(
    "prod/database/temp-user", 
    "Temporary database user password", 
    24
);

Password Complexity Validation

public class PasswordComplexityChecker {
    
    public static class ComplexityRequirements {
        public int minLength = 8;
        public boolean requireUppercase = true;
        public boolean requireLowercase = true;
        public boolean requireNumbers = true;
        public boolean requireSpecialChars = true;
        public String forbiddenChars = "";
    }
    
    public boolean meetsRequirements(String password, ComplexityRequirements requirements) {
        if (password.length() < requirements.minLength) {
            return false;
        }
        
        boolean hasUpper = password.chars().anyMatch(Character::isUpperCase);
        boolean hasLower = password.chars().anyMatch(Character::isLowerCase);
        boolean hasDigit = password.chars().anyMatch(Character::isDigit);
        boolean hasSpecial = password.chars().anyMatch(ch -> !Character.isLetterOrDigit(ch));
        
        if (requirements.requireUppercase && !hasUpper) return false;
        if (requirements.requireLowercase && !hasLower) return false;
        if (requirements.requireNumbers && !hasDigit) return false;
        if (requirements.requireSpecialChars && !hasSpecial) return false;
        
        // Check forbidden characters
        for (char forbidden : requirements.forbiddenChars.toCharArray()) {
            if (password.indexOf(forbidden) >= 0) {
                return false;
            }
        }
        
        return true;
    }
    
    public String generateCompliantPassword(ComplexityRequirements requirements) {
        GetRandomPasswordRequest.Builder requestBuilder = new GetRandomPasswordRequest()
            .withPasswordLength((long) Math.max(requirements.minLength, 12))
            .withRequireEachIncludedType(true);
        
        if (!requirements.requireUppercase) {
            requestBuilder.withExcludeUppercase(true);
        }
        if (!requirements.requireLowercase) {
            requestBuilder.withExcludeLowercase(true);
        }
        if (!requirements.requireNumbers) {
            requestBuilder.withExcludeNumbers(true);
        }
        if (!requirements.requireSpecialChars) {
            requestBuilder.withExcludePunctuation(true);
        }
        if (!requirements.forbiddenChars.isEmpty()) {
            requestBuilder.withExcludeCharacters(requirements.forbiddenChars);
        }
        
        GetRandomPasswordResult result = client.getRandomPassword(requestBuilder);
        return result.getRandomPassword();
    }
}

Resource Policy Validation

Validate IAM resource policies before applying them to secrets to ensure they follow security best practices and don't introduce vulnerabilities.

ValidateResourcePolicyRequest

class ValidateResourcePolicyRequest extends AmazonWebServiceRequest {
    String secretId;                          // Secret identifier (optional)
    String resourcePolicy;                    // Required: JSON policy document
}

ValidateResourcePolicyResult

class ValidateResourcePolicyResult {
    Boolean policyValidationPassed;           // Overall validation result
    List<ValidationErrorsEntry> validationErrors; // Detailed validation errors
}

ValidationErrorsEntry

class ValidationErrorsEntry {
    String checkName;                         // Name of the validation check that failed
    String errorMessage;                      // Detailed error description
}

Basic Policy Validation

// Validate a resource policy before applying
String policyDocument = "{\n" +
    "  \"Version\": \"2012-10-17\",\n" +
    "  \"Statement\": [\n" +
    "    {\n" +
    "      \"Effect\": \"Allow\",\n" +
    "      \"Principal\": {\n" +
    "        \"AWS\": \"arn:aws:iam::123456789012:role/MyRole\"\n" +
    "      },\n" +
    "      \"Action\": \"secretsmanager:GetSecretValue\",\n" +
    "      \"Resource\": \"*\"\n" +
    "    }\n" +
    "  ]\n" +
    "}";

ValidateResourcePolicyRequest validateRequest = new ValidateResourcePolicyRequest()
    .withResourcePolicy(policyDocument);

ValidateResourcePolicyResult validateResult = client.validateResourcePolicy(validateRequest);

if (validateResult.getPolicyValidationPassed()) {
    System.out.println("Policy validation passed - safe to apply");
} else {
    System.out.println("Policy validation failed:");
    for (ValidationErrorsEntry error : validateResult.getValidationErrors()) {
        System.out.println("  Check: " + error.getCheckName());
        System.out.println("  Error: " + error.getErrorMessage());
    }
}

Advanced Policy Validation

public class PolicyValidator {
    
    private final AWSSecretsManager client;
    
    public PolicyValidator(AWSSecretsManager client) {
        this.client = client;
    }
    
    public ValidationReport validatePolicy(String policyDocument, String secretId) {
        ValidateResourcePolicyRequest request = new ValidateResourcePolicyRequest()
            .withResourcePolicy(policyDocument)
            .withSecretId(secretId);
        
        try {
            ValidateResourcePolicyResult result = client.validateResourcePolicy(request);
            
            return new ValidationReport(
                result.getPolicyValidationPassed(),
                result.getValidationErrors()
            );
            
        } catch (Exception e) {
            ValidationReport report = new ValidationReport(false, new ArrayList<>());
            report.addError("VALIDATION_FAILED", "Policy validation service error: " + e.getMessage());
            return report;
        }
    }
    
    public static class ValidationReport {
        private final boolean passed;
        private final List<ValidationErrorsEntry> errors;
        
        public ValidationReport(boolean passed, List<ValidationErrorsEntry> errors) {
            this.passed = passed;
            this.errors = errors != null ? errors : new ArrayList<>();
        }
        
        public boolean isPassed() { return passed; }
        public List<ValidationErrorsEntry> getErrors() { return errors; }
        
        public void addError(String checkName, String errorMessage) {
            ValidationErrorsEntry error = new ValidationErrorsEntry()
                .withCheckName(checkName)
                .withErrorMessage(errorMessage);
            errors.add(error);
        }
        
        public void printReport() {
            if (passed) {
                System.out.println("✓ Policy validation PASSED");
            } else {
                System.out.println("✗ Policy validation FAILED");
                for (ValidationErrorsEntry error : errors) {
                    System.out.println("  • " + error.getCheckName() + ": " + error.getErrorMessage());
                }
            }
        }
        
        public boolean hasSecurityRisks() {
            return errors.stream().anyMatch(error -> 
                error.getCheckName().toLowerCase().contains("security") ||
                error.getCheckName().toLowerCase().contains("public") ||
                error.getErrorMessage().toLowerCase().contains("security risk"));
        }
    }
}

Policy Validation Workflow

public class SecurePolicyManager {
    
    private final AWSSecretsManager client;
    private final PolicyValidator validator;
    
    public SecurePolicyManager(AWSSecretsManager client) {
        this.client = client;
        this.validator = new PolicyValidator(client);
    }
    
    public boolean applyPolicyWithValidation(String secretId, String policyDocument) {
        // Step 1: Validate the policy
        PolicyValidator.ValidationReport report = validator.validatePolicy(policyDocument, secretId);
        
        System.out.println("Policy Validation Report:");
        report.printReport();
        
        // Step 2: Check for security risks
        if (report.hasSecurityRisks()) {
            System.err.println("BLOCKED: Policy contains security risks and will not be applied");
            return false;
        }
        
        // Step 3: Apply policy if validation passed
        if (report.isPassed()) {
            try {
                PutResourcePolicyRequest putRequest = new PutResourcePolicyRequest()
                    .withSecretId(secretId)
                    .withResourcePolicy(policyDocument)
                    .withBlockPublicPolicy(true);
                
                PutResourcePolicyResult putResult = client.putResourcePolicy(putRequest);
                System.out.println("Policy successfully applied to: " + putResult.getName());
                return true;
                
            } catch (Exception e) {
                System.err.println("Failed to apply policy: " + e.getMessage());
                return false;
            }
        } else {
            System.err.println("Policy validation failed - not applying");
            return false;
        }
    }
    
    public void auditExistingPolicies(List<String> secretIds) {
        System.out.println("Policy Audit Report");
        System.out.println("==================");
        
        for (String secretId : secretIds) {
            try {
                GetResourcePolicyRequest getRequest = new GetResourcePolicyRequest()
                    .withSecretId(secretId);
                
                GetResourcePolicyResult getResult = client.getResourcePolicy(getRequest);
                String currentPolicy = getResult.getResourcePolicy();
                
                if (currentPolicy != null) {
                    PolicyValidator.ValidationReport report = validator.validatePolicy(currentPolicy, secretId);
                    
                    System.out.println("\nSecret: " + secretId);
                    if (report.isPassed()) {
                        System.out.println("Status: ✓ COMPLIANT");
                    } else {
                        System.out.println("Status: ✗ NON-COMPLIANT");
                        for (ValidationErrorsEntry error : report.getErrors()) {
                            System.out.println("  Issue: " + error.getErrorMessage());
                        }
                    }
                } else {
                    System.out.println("\nSecret: " + secretId);
                    System.out.println("Status: No resource policy");
                }
                
            } catch (ResourceNotFoundException e) {
                System.out.println("\nSecret: " + secretId);
                System.out.println("Status: No resource policy");
            } catch (Exception e) {
                System.out.println("\nSecret: " + secretId);
                System.out.println("Status: Error - " + e.getMessage());
            }
        }
    }
}

Common Validation Scenarios

// Test different policy scenarios
public void testPolicyValidationScenarios() {
    
    // 1. Valid restrictive policy
    String validPolicy = "{\n" +
        "  \"Version\": \"2012-10-17\",\n" +
        "  \"Statement\": [\n" +
        "    {\n" +
        "      \"Effect\": \"Allow\",\n" +
        "      \"Principal\": {\n" +
        "        \"AWS\": \"arn:aws:iam::123456789012:role/MySpecificRole\"\n" +
        "      },\n" +
        "      \"Action\": \"secretsmanager:GetSecretValue\",\n" +
        "      \"Resource\": \"*\",\n" +
        "      \"Condition\": {\n" +
        "        \"StringEquals\": {\n" +
        "          \"aws:userid\": \"AIDACKCEVSQ6C2EXAMPLE\"\n" +
        "        }\n" +
        "      }\n" +
        "    }\n" +
        "  ]\n" +
        "}";
    
    // 2. Potentially problematic policy (public access)
    String publicPolicy = "{\n" +
        "  \"Version\": \"2012-10-17\",\n" +
        "  \"Statement\": [\n" +
        "    {\n" +
        "      \"Effect\": \"Allow\",\n" +
        "      \"Principal\": \"*\",\n" +
        "      \"Action\": \"secretsmanager:GetSecretValue\",\n" +
        "      \"Resource\": \"*\"\n" +
        "    }\n" +
        "  ]\n" +
        "}";
    
    // 3. Malformed policy
    String malformedPolicy = "{\n" +
        "  \"Version\": \"2012-10-17\",\n" +
        "  \"Statement\": [\n" +
        "    {\n" +
        "      \"Effect\": \"Allow\",\n" +
        "      \"Principal\": {\n" +
        "        \"AWS\": \"invalid-arn\"\n" +
        "      },\n" +
        "      \"Action\": \"invalid-action\",\n" +
        "      \"Resource\": \"*\"\n" +
        "    }\n" +
        "  ]\n" +
        "}";
    
    String[] policies = {validPolicy, publicPolicy, malformedPolicy};
    String[] policyNames = {"Valid Restrictive", "Public Access", "Malformed"};
    
    for (int i = 0; i < policies.length; i++) {
        System.out.println("\nTesting: " + policyNames[i]);
        System.out.println("----------------------------------------");
        
        ValidateResourcePolicyRequest request = new ValidateResourcePolicyRequest()
            .withResourcePolicy(policies[i]);
        
        try {
            ValidateResourcePolicyResult result = client.validateResourcePolicy(request);
            
            if (result.getPolicyValidationPassed()) {
                System.out.println("✓ Validation PASSED");
            } else {
                System.out.println("✗ Validation FAILED");
                for (ValidationErrorsEntry error : result.getValidationErrors()) {
                    System.out.println("  " + error.getCheckName() + ": " + error.getErrorMessage());
                }
            }
        } catch (Exception e) {
            System.out.println("✗ Validation ERROR: " + e.getMessage());
        }
    }
}

Utility Helpers

Secret Name Utilities

public class SecretNameUtils {
    
    // Generate standardized secret names
    public static String generateSecretName(String environment, String service, 
                                          String component, String type) {
        return String.format("%s/%s/%s/%s", 
                           environment.toLowerCase(), 
                           service.toLowerCase(), 
                           component.toLowerCase(), 
                           type.toLowerCase());
    }
    
    // Parse secret name components
    public static class SecretNameParts {
        public final String environment;
        public final String service;
        public final String component;
        public final String type;
        
        public SecretNameParts(String environment, String service, String component, String type) {
            this.environment = environment;
            this.service = service;
            this.component = component;
            this.type = type;
        }
    }
    
    public static SecretNameParts parseSecretName(String secretName) {
        String[] parts = secretName.split("/");
        if (parts.length != 4) {
            throw new IllegalArgumentException("Secret name must follow pattern: environment/service/component/type");
        }
        return new SecretNameParts(parts[0], parts[1], parts[2], parts[3]);
    }
    
    // Validate secret name format
    public static boolean isValidSecretName(String secretName) {
        if (secretName == null || secretName.trim().isEmpty()) {
            return false;
        }
        
        // Check length (1-512 characters)
        if (secretName.length() > 512) {
            return false;
        }
        
        // Check valid characters (alphanumeric, hyphens, underscores, periods, forward slashes)
        return secretName.matches("^[a-zA-Z0-9/_.-]+$");
    }
}

Error Handling Utilities

public class SecretsManagerErrorHandler {
    
    public static void handleCommonErrors(Exception e) {
        if (e instanceof ResourceNotFoundException) {
            System.err.println("Resource not found: " + e.getMessage());
        } else if (e instanceof InvalidParameterException) {
            System.err.println("Invalid parameter: " + e.getMessage());
        } else if (e instanceof LimitExceededException) {
            System.err.println("Service limit exceeded: " + e.getMessage());
        } else if (e instanceof DecryptionFailureException) {
            System.err.println("Decryption failed - check KMS permissions: " + e.getMessage());
        } else if (e instanceof EncryptionFailureException) {
            System.err.println("Encryption failed - check KMS key: " + e.getMessage());
        } else if (e instanceof ResourceExistsException) {
            System.err.println("Resource already exists: " + e.getMessage());
        } else if (e instanceof AWSSecretsManagerException) {
            System.err.println("Secrets Manager service error: " + e.getMessage());
        } else {
            System.err.println("Unexpected error: " + e.getMessage());
        }
    }
}

Best Practices

Password Generation

  1. Appropriate Length: Use sufficient length for security (minimum 12 characters)
  2. Character Diversity: Include multiple character types unless restricted
  3. Avoid Confusing Characters: Exclude similar-looking characters (0O1lI) for human-readable passwords
  4. Context-Specific: Adapt requirements to the target system's capabilities
  5. Entropy: Prefer longer passwords over complex requirements when possible

Policy Validation

  1. Pre-Validation: Always validate policies before applying to production
  2. Least Privilege: Ensure policies grant minimal necessary permissions
  3. Regular Audits: Periodically validate existing policies for compliance
  4. Security Scanning: Check for potential security risks in policy statements
  5. Documentation: Document policy purpose and any special conditions
  6. Testing: Test policies in development environments first

General Utilities

  1. Error Handling: Implement comprehensive error handling for all operations
  2. Logging: Log utility operations for audit and debugging purposes
  3. Validation: Validate inputs before making API calls
  4. Retries: Implement appropriate retry logic for transient failures
  5. Monitoring: Monitor utility usage patterns and performance

Install with Tessl CLI

npx tessl i tessl/maven-com-amazonaws--aws-java-sdk-secretsmanager

docs

index.md

policies-tags.md

replication.md

rotation.md

secret-management.md

utilities.md

tile.json