or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdpolicies-tags.mdreplication.mdrotation.mdsecret-management.mdutilities.md

utilities.mddocs/

0

# Utility Operations

1

2

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

3

4

## Random Password Generation

5

6

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.

7

8

### GetRandomPasswordRequest

9

10

```java { .api }

11

class GetRandomPasswordRequest extends AmazonWebServiceRequest {

12

Long passwordLength; // Password length (4-4096, default: 32)

13

String excludeCharacters; // Characters to exclude

14

Boolean excludeNumbers; // Exclude numeric characters (0-9)

15

Boolean excludePunctuation; // Exclude punctuation (!@#$%^&*()_+-=[]{}|;:,.<>?)

16

Boolean excludeUppercase; // Exclude uppercase letters (A-Z)

17

Boolean excludeLowercase; // Exclude lowercase letters (a-z)

18

Boolean includeSpace; // Include space character

19

Boolean requireEachIncludedType; // Require at least one character from each enabled type

20

}

21

```

22

23

### GetRandomPasswordResult

24

25

```java { .api }

26

class GetRandomPasswordResult {

27

String randomPassword; // Generated password

28

}

29

```

30

31

### Basic Password Generation

32

33

```java { .api }

34

// Generate a basic 32-character password

35

GetRandomPasswordRequest basicRequest = new GetRandomPasswordRequest();

36

37

GetRandomPasswordResult basicResult = client.getRandomPassword(basicRequest);

38

String basicPassword = basicResult.getRandomPassword();

39

System.out.println("Generated password: " + basicPassword);

40

41

// Generate a 16-character password

42

GetRandomPasswordRequest shortRequest = new GetRandomPasswordRequest()

43

.withPasswordLength(16L);

44

45

GetRandomPasswordResult shortResult = client.getRandomPassword(shortRequest);

46

String shortPassword = shortResult.getRandomPassword();

47

```

48

49

### Custom Password Requirements

50

51

```java { .api }

52

// Generate password without special characters

53

GetRandomPasswordRequest alphanumericRequest = new GetRandomPasswordRequest()

54

.withPasswordLength(20L)

55

.withExcludePunctuation(true)

56

.withRequireEachIncludedType(true);

57

58

GetRandomPasswordResult alphanumericResult = client.getRandomPassword(alphanumericRequest);

59

String alphanumericPassword = alphanumericResult.getRandomPassword();

60

61

// Generate password with specific exclusions

62

GetRandomPasswordRequest customRequest = new GetRandomPasswordRequest()

63

.withPasswordLength(24L)

64

.withExcludeCharacters("0O1lI") // Exclude confusing characters

65

.withRequireEachIncludedType(true);

66

67

GetRandomPasswordResult customResult = client.getRandomPassword(customRequest);

68

String customPassword = customResult.getRandomPassword();

69

70

// Generate a simple password (letters and numbers only)

71

GetRandomPasswordRequest simpleRequest = new GetRandomPasswordRequest()

72

.withPasswordLength(12L)

73

.withExcludePunctuation(true)

74

.withRequireEachIncludedType(true);

75

76

GetRandomPasswordResult simpleResult = client.getRandomPassword(simpleRequest);

77

String simplePassword = simpleResult.getRandomPassword();

78

```

79

80

### Advanced Password Generation

81

82

```java { .api }

83

// Database-friendly password (no special chars that might cause issues)

84

GetRandomPasswordRequest dbFriendlyRequest = new GetRandomPasswordRequest()

85

.withPasswordLength(32L)

86

.withExcludePunctuation(true)

87

.withExcludeCharacters("'\"\\`") // Exclude SQL problematic characters

88

.withRequireEachIncludedType(true);

89

90

GetRandomPasswordResult dbFriendlyResult = client.getRandomPassword(dbFriendlyRequest);

91

92

// URL-safe password (no characters that need URL encoding)

93

GetRandomPasswordRequest urlSafeRequest = new GetRandomPasswordRequest()

94

.withPasswordLength(28L)

95

.withExcludeCharacters("!@#$%^&*()+={}[]|\\:;\"'<>,.?/~`")

96

.withRequireEachIncludedType(true);

97

98

GetRandomPasswordResult urlSafeResult = client.getRandomPassword(urlSafeRequest);

99

100

// High entropy password with all character types

101

GetRandomPasswordRequest highEntropyRequest = new GetRandomPasswordRequest()

102

.withPasswordLength(40L)

103

.withIncludeSpace(false) // Avoid spaces for compatibility

104

.withRequireEachIncludedType(true);

105

106

GetRandomPasswordResult highEntropyResult = client.getRandomPassword(highEntropyRequest);

107

```

108

109

### Password Generation Patterns

110

111

```java { .api }

112

public class PasswordGenerator {

113

114

private final AWSSecretsManager client;

115

116

public PasswordGenerator(AWSSecretsManager client) {

117

this.client = client;

118

}

119

120

// Generate password for database users

121

public String generateDatabasePassword() {

122

GetRandomPasswordRequest request = new GetRandomPasswordRequest()

123

.withPasswordLength(24L)

124

.withExcludePunctuation(true)

125

.withExcludeCharacters("'\"\\`") // Avoid SQL injection issues

126

.withRequireEachIncludedType(true);

127

128

return client.getRandomPassword(request).getRandomPassword();

129

}

130

131

// Generate password for API keys (alphanumeric only)

132

public String generateAPIPassword() {

133

GetRandomPasswordRequest request = new GetRandomPasswordRequest()

134

.withPasswordLength(32L)

135

.withExcludePunctuation(true)

136

.withRequireEachIncludedType(true);

137

138

return client.getRandomPassword(request).getRandomPassword();

139

}

140

141

// Generate secure password with maximum entropy

142

public String generateSecurePassword(int length) {

143

GetRandomPasswordRequest request = new GetRandomPasswordRequest()

144

.withPasswordLength((long) length)

145

.withRequireEachIncludedType(true);

146

147

return client.getRandomPassword(request).getRandomPassword();

148

}

149

150

// Generate password meeting corporate policy

151

public String generateCorporatePassword() {

152

GetRandomPasswordRequest request = new GetRandomPasswordRequest()

153

.withPasswordLength(16L)

154

.withRequireEachIncludedType(true)

155

.withExcludeCharacters("0O1lI5S"); // Exclude confusing characters

156

157

return client.getRandomPassword(request).getRandomPassword();

158

}

159

160

// Generate temporary password (shorter, alphanumeric)

161

public String generateTemporaryPassword() {

162

GetRandomPasswordRequest request = new GetRandomPasswordRequest()

163

.withPasswordLength(8L)

164

.withExcludePunctuation(true)

165

.withExcludeCharacters("0O1lI")

166

.withRequireEachIncludedType(true);

167

168

return client.getRandomPassword(request).getRandomPassword();

169

}

170

}

171

```

172

173

### Automated Secret Creation with Generated Passwords

174

175

```java { .api }

176

// Create secret with automatically generated password

177

public String createSecretWithGeneratedPassword(String secretName,

178

String description,

179

int passwordLength) {

180

try {

181

// Generate secure password

182

GetRandomPasswordRequest passwordRequest = new GetRandomPasswordRequest()

183

.withPasswordLength((long) passwordLength)

184

.withRequireEachIncludedType(true);

185

186

GetRandomPasswordResult passwordResult = client.getRandomPassword(passwordRequest);

187

String generatedPassword = passwordResult.getRandomPassword();

188

189

// Create secret with generated password

190

CreateSecretRequest createRequest = new CreateSecretRequest()

191

.withName(secretName)

192

.withSecretString(generatedPassword)

193

.withDescription(description);

194

195

CreateSecretResult createResult = client.createSecret(createRequest);

196

197

System.out.println("Created secret: " + createResult.getName());

198

System.out.println("Secret ARN: " + createResult.getArn());

199

200

return generatedPassword;

201

202

} catch (Exception e) {

203

System.err.println("Failed to create secret with generated password: " + e.getMessage());

204

throw e;

205

}

206

}

207

208

// Usage

209

String password = createSecretWithGeneratedPassword(

210

"prod/database/temp-user",

211

"Temporary database user password",

212

24

213

);

214

```

215

216

### Password Complexity Validation

217

218

```java { .api }

219

public class PasswordComplexityChecker {

220

221

public static class ComplexityRequirements {

222

public int minLength = 8;

223

public boolean requireUppercase = true;

224

public boolean requireLowercase = true;

225

public boolean requireNumbers = true;

226

public boolean requireSpecialChars = true;

227

public String forbiddenChars = "";

228

}

229

230

public boolean meetsRequirements(String password, ComplexityRequirements requirements) {

231

if (password.length() < requirements.minLength) {

232

return false;

233

}

234

235

boolean hasUpper = password.chars().anyMatch(Character::isUpperCase);

236

boolean hasLower = password.chars().anyMatch(Character::isLowerCase);

237

boolean hasDigit = password.chars().anyMatch(Character::isDigit);

238

boolean hasSpecial = password.chars().anyMatch(ch -> !Character.isLetterOrDigit(ch));

239

240

if (requirements.requireUppercase && !hasUpper) return false;

241

if (requirements.requireLowercase && !hasLower) return false;

242

if (requirements.requireNumbers && !hasDigit) return false;

243

if (requirements.requireSpecialChars && !hasSpecial) return false;

244

245

// Check forbidden characters

246

for (char forbidden : requirements.forbiddenChars.toCharArray()) {

247

if (password.indexOf(forbidden) >= 0) {

248

return false;

249

}

250

}

251

252

return true;

253

}

254

255

public String generateCompliantPassword(ComplexityRequirements requirements) {

256

GetRandomPasswordRequest.Builder requestBuilder = new GetRandomPasswordRequest()

257

.withPasswordLength((long) Math.max(requirements.minLength, 12))

258

.withRequireEachIncludedType(true);

259

260

if (!requirements.requireUppercase) {

261

requestBuilder.withExcludeUppercase(true);

262

}

263

if (!requirements.requireLowercase) {

264

requestBuilder.withExcludeLowercase(true);

265

}

266

if (!requirements.requireNumbers) {

267

requestBuilder.withExcludeNumbers(true);

268

}

269

if (!requirements.requireSpecialChars) {

270

requestBuilder.withExcludePunctuation(true);

271

}

272

if (!requirements.forbiddenChars.isEmpty()) {

273

requestBuilder.withExcludeCharacters(requirements.forbiddenChars);

274

}

275

276

GetRandomPasswordResult result = client.getRandomPassword(requestBuilder);

277

return result.getRandomPassword();

278

}

279

}

280

```

281

282

## Resource Policy Validation

283

284

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

285

286

### ValidateResourcePolicyRequest

287

288

```java { .api }

289

class ValidateResourcePolicyRequest extends AmazonWebServiceRequest {

290

String secretId; // Secret identifier (optional)

291

String resourcePolicy; // Required: JSON policy document

292

}

293

```

294

295

### ValidateResourcePolicyResult

296

297

```java { .api }

298

class ValidateResourcePolicyResult {

299

Boolean policyValidationPassed; // Overall validation result

300

List<ValidationErrorsEntry> validationErrors; // Detailed validation errors

301

}

302

```

303

304

### ValidationErrorsEntry

305

306

```java { .api }

307

class ValidationErrorsEntry {

308

String checkName; // Name of the validation check that failed

309

String errorMessage; // Detailed error description

310

}

311

```

312

313

### Basic Policy Validation

314

315

```java { .api }

316

// Validate a resource policy before applying

317

String policyDocument = "{\n" +

318

" \"Version\": \"2012-10-17\",\n" +

319

" \"Statement\": [\n" +

320

" {\n" +

321

" \"Effect\": \"Allow\",\n" +

322

" \"Principal\": {\n" +

323

" \"AWS\": \"arn:aws:iam::123456789012:role/MyRole\"\n" +

324

" },\n" +

325

" \"Action\": \"secretsmanager:GetSecretValue\",\n" +

326

" \"Resource\": \"*\"\n" +

327

" }\n" +

328

" ]\n" +

329

"}";

330

331

ValidateResourcePolicyRequest validateRequest = new ValidateResourcePolicyRequest()

332

.withResourcePolicy(policyDocument);

333

334

ValidateResourcePolicyResult validateResult = client.validateResourcePolicy(validateRequest);

335

336

if (validateResult.getPolicyValidationPassed()) {

337

System.out.println("Policy validation passed - safe to apply");

338

} else {

339

System.out.println("Policy validation failed:");

340

for (ValidationErrorsEntry error : validateResult.getValidationErrors()) {

341

System.out.println(" Check: " + error.getCheckName());

342

System.out.println(" Error: " + error.getErrorMessage());

343

}

344

}

345

```

346

347

### Advanced Policy Validation

348

349

```java { .api }

350

public class PolicyValidator {

351

352

private final AWSSecretsManager client;

353

354

public PolicyValidator(AWSSecretsManager client) {

355

this.client = client;

356

}

357

358

public ValidationReport validatePolicy(String policyDocument, String secretId) {

359

ValidateResourcePolicyRequest request = new ValidateResourcePolicyRequest()

360

.withResourcePolicy(policyDocument)

361

.withSecretId(secretId);

362

363

try {

364

ValidateResourcePolicyResult result = client.validateResourcePolicy(request);

365

366

return new ValidationReport(

367

result.getPolicyValidationPassed(),

368

result.getValidationErrors()

369

);

370

371

} catch (Exception e) {

372

ValidationReport report = new ValidationReport(false, new ArrayList<>());

373

report.addError("VALIDATION_FAILED", "Policy validation service error: " + e.getMessage());

374

return report;

375

}

376

}

377

378

public static class ValidationReport {

379

private final boolean passed;

380

private final List<ValidationErrorsEntry> errors;

381

382

public ValidationReport(boolean passed, List<ValidationErrorsEntry> errors) {

383

this.passed = passed;

384

this.errors = errors != null ? errors : new ArrayList<>();

385

}

386

387

public boolean isPassed() { return passed; }

388

public List<ValidationErrorsEntry> getErrors() { return errors; }

389

390

public void addError(String checkName, String errorMessage) {

391

ValidationErrorsEntry error = new ValidationErrorsEntry()

392

.withCheckName(checkName)

393

.withErrorMessage(errorMessage);

394

errors.add(error);

395

}

396

397

public void printReport() {

398

if (passed) {

399

System.out.println("✓ Policy validation PASSED");

400

} else {

401

System.out.println("✗ Policy validation FAILED");

402

for (ValidationErrorsEntry error : errors) {

403

System.out.println(" • " + error.getCheckName() + ": " + error.getErrorMessage());

404

}

405

}

406

}

407

408

public boolean hasSecurityRisks() {

409

return errors.stream().anyMatch(error ->

410

error.getCheckName().toLowerCase().contains("security") ||

411

error.getCheckName().toLowerCase().contains("public") ||

412

error.getErrorMessage().toLowerCase().contains("security risk"));

413

}

414

}

415

}

416

```

417

418

### Policy Validation Workflow

419

420

```java { .api }

421

public class SecurePolicyManager {

422

423

private final AWSSecretsManager client;

424

private final PolicyValidator validator;

425

426

public SecurePolicyManager(AWSSecretsManager client) {

427

this.client = client;

428

this.validator = new PolicyValidator(client);

429

}

430

431

public boolean applyPolicyWithValidation(String secretId, String policyDocument) {

432

// Step 1: Validate the policy

433

PolicyValidator.ValidationReport report = validator.validatePolicy(policyDocument, secretId);

434

435

System.out.println("Policy Validation Report:");

436

report.printReport();

437

438

// Step 2: Check for security risks

439

if (report.hasSecurityRisks()) {

440

System.err.println("BLOCKED: Policy contains security risks and will not be applied");

441

return false;

442

}

443

444

// Step 3: Apply policy if validation passed

445

if (report.isPassed()) {

446

try {

447

PutResourcePolicyRequest putRequest = new PutResourcePolicyRequest()

448

.withSecretId(secretId)

449

.withResourcePolicy(policyDocument)

450

.withBlockPublicPolicy(true);

451

452

PutResourcePolicyResult putResult = client.putResourcePolicy(putRequest);

453

System.out.println("Policy successfully applied to: " + putResult.getName());

454

return true;

455

456

} catch (Exception e) {

457

System.err.println("Failed to apply policy: " + e.getMessage());

458

return false;

459

}

460

} else {

461

System.err.println("Policy validation failed - not applying");

462

return false;

463

}

464

}

465

466

public void auditExistingPolicies(List<String> secretIds) {

467

System.out.println("Policy Audit Report");

468

System.out.println("==================");

469

470

for (String secretId : secretIds) {

471

try {

472

GetResourcePolicyRequest getRequest = new GetResourcePolicyRequest()

473

.withSecretId(secretId);

474

475

GetResourcePolicyResult getResult = client.getResourcePolicy(getRequest);

476

String currentPolicy = getResult.getResourcePolicy();

477

478

if (currentPolicy != null) {

479

PolicyValidator.ValidationReport report = validator.validatePolicy(currentPolicy, secretId);

480

481

System.out.println("\nSecret: " + secretId);

482

if (report.isPassed()) {

483

System.out.println("Status: ✓ COMPLIANT");

484

} else {

485

System.out.println("Status: ✗ NON-COMPLIANT");

486

for (ValidationErrorsEntry error : report.getErrors()) {

487

System.out.println(" Issue: " + error.getErrorMessage());

488

}

489

}

490

} else {

491

System.out.println("\nSecret: " + secretId);

492

System.out.println("Status: No resource policy");

493

}

494

495

} catch (ResourceNotFoundException e) {

496

System.out.println("\nSecret: " + secretId);

497

System.out.println("Status: No resource policy");

498

} catch (Exception e) {

499

System.out.println("\nSecret: " + secretId);

500

System.out.println("Status: Error - " + e.getMessage());

501

}

502

}

503

}

504

}

505

```

506

507

### Common Validation Scenarios

508

509

```java { .api }

510

// Test different policy scenarios

511

public void testPolicyValidationScenarios() {

512

513

// 1. Valid restrictive policy

514

String validPolicy = "{\n" +

515

" \"Version\": \"2012-10-17\",\n" +

516

" \"Statement\": [\n" +

517

" {\n" +

518

" \"Effect\": \"Allow\",\n" +

519

" \"Principal\": {\n" +

520

" \"AWS\": \"arn:aws:iam::123456789012:role/MySpecificRole\"\n" +

521

" },\n" +

522

" \"Action\": \"secretsmanager:GetSecretValue\",\n" +

523

" \"Resource\": \"*\",\n" +

524

" \"Condition\": {\n" +

525

" \"StringEquals\": {\n" +

526

" \"aws:userid\": \"AIDACKCEVSQ6C2EXAMPLE\"\n" +

527

" }\n" +

528

" }\n" +

529

" }\n" +

530

" ]\n" +

531

"}";

532

533

// 2. Potentially problematic policy (public access)

534

String publicPolicy = "{\n" +

535

" \"Version\": \"2012-10-17\",\n" +

536

" \"Statement\": [\n" +

537

" {\n" +

538

" \"Effect\": \"Allow\",\n" +

539

" \"Principal\": \"*\",\n" +

540

" \"Action\": \"secretsmanager:GetSecretValue\",\n" +

541

" \"Resource\": \"*\"\n" +

542

" }\n" +

543

" ]\n" +

544

"}";

545

546

// 3. Malformed policy

547

String malformedPolicy = "{\n" +

548

" \"Version\": \"2012-10-17\",\n" +

549

" \"Statement\": [\n" +

550

" {\n" +

551

" \"Effect\": \"Allow\",\n" +

552

" \"Principal\": {\n" +

553

" \"AWS\": \"invalid-arn\"\n" +

554

" },\n" +

555

" \"Action\": \"invalid-action\",\n" +

556

" \"Resource\": \"*\"\n" +

557

" }\n" +

558

" ]\n" +

559

"}";

560

561

String[] policies = {validPolicy, publicPolicy, malformedPolicy};

562

String[] policyNames = {"Valid Restrictive", "Public Access", "Malformed"};

563

564

for (int i = 0; i < policies.length; i++) {

565

System.out.println("\nTesting: " + policyNames[i]);

566

System.out.println("----------------------------------------");

567

568

ValidateResourcePolicyRequest request = new ValidateResourcePolicyRequest()

569

.withResourcePolicy(policies[i]);

570

571

try {

572

ValidateResourcePolicyResult result = client.validateResourcePolicy(request);

573

574

if (result.getPolicyValidationPassed()) {

575

System.out.println("✓ Validation PASSED");

576

} else {

577

System.out.println("✗ Validation FAILED");

578

for (ValidationErrorsEntry error : result.getValidationErrors()) {

579

System.out.println(" " + error.getCheckName() + ": " + error.getErrorMessage());

580

}

581

}

582

} catch (Exception e) {

583

System.out.println("✗ Validation ERROR: " + e.getMessage());

584

}

585

}

586

}

587

```

588

589

## Utility Helpers

590

591

### Secret Name Utilities

592

593

```java { .api }

594

public class SecretNameUtils {

595

596

// Generate standardized secret names

597

public static String generateSecretName(String environment, String service,

598

String component, String type) {

599

return String.format("%s/%s/%s/%s",

600

environment.toLowerCase(),

601

service.toLowerCase(),

602

component.toLowerCase(),

603

type.toLowerCase());

604

}

605

606

// Parse secret name components

607

public static class SecretNameParts {

608

public final String environment;

609

public final String service;

610

public final String component;

611

public final String type;

612

613

public SecretNameParts(String environment, String service, String component, String type) {

614

this.environment = environment;

615

this.service = service;

616

this.component = component;

617

this.type = type;

618

}

619

}

620

621

public static SecretNameParts parseSecretName(String secretName) {

622

String[] parts = secretName.split("/");

623

if (parts.length != 4) {

624

throw new IllegalArgumentException("Secret name must follow pattern: environment/service/component/type");

625

}

626

return new SecretNameParts(parts[0], parts[1], parts[2], parts[3]);

627

}

628

629

// Validate secret name format

630

public static boolean isValidSecretName(String secretName) {

631

if (secretName == null || secretName.trim().isEmpty()) {

632

return false;

633

}

634

635

// Check length (1-512 characters)

636

if (secretName.length() > 512) {

637

return false;

638

}

639

640

// Check valid characters (alphanumeric, hyphens, underscores, periods, forward slashes)

641

return secretName.matches("^[a-zA-Z0-9/_.-]+$");

642

}

643

}

644

```

645

646

### Error Handling Utilities

647

648

```java { .api }

649

public class SecretsManagerErrorHandler {

650

651

public static void handleCommonErrors(Exception e) {

652

if (e instanceof ResourceNotFoundException) {

653

System.err.println("Resource not found: " + e.getMessage());

654

} else if (e instanceof InvalidParameterException) {

655

System.err.println("Invalid parameter: " + e.getMessage());

656

} else if (e instanceof LimitExceededException) {

657

System.err.println("Service limit exceeded: " + e.getMessage());

658

} else if (e instanceof DecryptionFailureException) {

659

System.err.println("Decryption failed - check KMS permissions: " + e.getMessage());

660

} else if (e instanceof EncryptionFailureException) {

661

System.err.println("Encryption failed - check KMS key: " + e.getMessage());

662

} else if (e instanceof ResourceExistsException) {

663

System.err.println("Resource already exists: " + e.getMessage());

664

} else if (e instanceof AWSSecretsManagerException) {

665

System.err.println("Secrets Manager service error: " + e.getMessage());

666

} else {

667

System.err.println("Unexpected error: " + e.getMessage());

668

}

669

}

670

}

671

```

672

673

## Best Practices

674

675

### Password Generation

676

1. **Appropriate Length**: Use sufficient length for security (minimum 12 characters)

677

2. **Character Diversity**: Include multiple character types unless restricted

678

3. **Avoid Confusing Characters**: Exclude similar-looking characters (0O1lI) for human-readable passwords

679

4. **Context-Specific**: Adapt requirements to the target system's capabilities

680

5. **Entropy**: Prefer longer passwords over complex requirements when possible

681

682

### Policy Validation

683

1. **Pre-Validation**: Always validate policies before applying to production

684

2. **Least Privilege**: Ensure policies grant minimal necessary permissions

685

3. **Regular Audits**: Periodically validate existing policies for compliance

686

4. **Security Scanning**: Check for potential security risks in policy statements

687

5. **Documentation**: Document policy purpose and any special conditions

688

6. **Testing**: Test policies in development environments first

689

690

### General Utilities

691

1. **Error Handling**: Implement comprehensive error handling for all operations

692

2. **Logging**: Log utility operations for audit and debugging purposes

693

3. **Validation**: Validate inputs before making API calls

694

4. **Retries**: Implement appropriate retry logic for transient failures

695

5. **Monitoring**: Monitor utility usage patterns and performance