---
title: "HashiCorp Vault - Multi-Environment Secrets"
lang: "en"
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/post/hashicorp-vault-multi-environment-secrets
---

![Blog post image for Multi-Environment Secret Management with HashiCorp Vault - Manage secrets securely across dev, staging, and production with HashiCorp Vault. This snippet demonstrates dynamic secret generation, rotation, and cross-environment secret syncing patterns.](/_astro/hero.B4H3tk7I_Z1skNfS.webp)

[Home](/)›[Codesnippets](/codesnippets)›[All Categories](/codesnippets/categories)›[Security](/codesnippets/categories/security)

Codesnippets

[Security](/codesnippets/categories/security)[Devops](/codesnippets/categories/devops)[Bash and Python](/codesnippets/bash-and-python)

# Multi-Environment Secret Management with HashiCorp Vault

[Mohammad Abu Mattar](/authors/mohammad-abu-mattar)Published: 03 Mar 202604 Mins read03 Mins listen

[Markdown for AI(opens in a new tab)](/post/hashicorp-vault-multi-environment-secrets/index.md "Open the plain-Markdown version of this page, for pasting into an AI tool")

TL;DR

Manage secrets securely across dev, staging, and production with HashiCorp Vault. This snippet demonstrates dynamic secret generation, rotation, and cross-environment secret syncing patterns.

Series

[Secret Management](/series/secret-management)1/1

All posts in this series (1)

Code Snippets1

1.  [Multi-Environment Secret Management with HashiCorp VaultYou are here](/codesnippets/post/hashicorp-vault-multi-environment-secrets)

### Multi-Environment Secret Management with HashiCorp Vault

Contents

[Managing secrets safely across multiple environments with HashiCorp Vault](#managing-secrets-safely-across-multiple-environments-with-hashicorp-vault)[The Problem](#the-problem)[Multi-environment secret chaos](#multi-environment-secret-chaos)[The Solution](#the-solution)[HashiCorp Vault overview](#hashicorp-vault-overview)[TL;DR](#tldr)[Installation and setup](#installation-and-setup)[Start Vault with Docker](#start-vault-with-docker)[CLI examples](#cli-examples)[Basic secret storage](#basic-secret-storage)[Organize secrets by environment](#organize-secrets-by-environment)[Programming examples](#programming-examples)[Python: fetch secrets](#python-fetch-secrets)[Node.js: fetch secrets](#nodejs-fetch-secrets)[Dynamic database credentials](#dynamic-database-credentials)[Configure the database secret engine](#configure-the-database-secret-engine)[Retrieve dynamic credentials](#retrieve-dynamic-credentials)[Python: use dynamic credentials](#python-use-dynamic-credentials)[Policy-based access control](#policy-based-access-control)[Create policies for different roles](#create-policies-for-different-roles)[Apply policies](#apply-policies)[Kubernetes integration](#kubernetes-integration)[Enable Kubernetes auth](#enable-kubernetes-auth)[Pod configuration](#pod-configuration)[Audit logging](#audit-logging)[Enable audit logging](#enable-audit-logging)[Query audit logs](#query-audit-logs)[Best practices](#best-practices)[1\. Use AppRole for applications](#1-use-approle-for-applications)[2\. Rotate secrets regularly](#2-rotate-secrets-regularly)[3\. Implement least privilege](#3-implement-least-privilege)[Resources](#resources)

### [Managing secrets safely across multiple environments with HashiCorp Vault](#managing-secrets-safely-across-multiple-environments-with-hashicorp-vault)

Storing secrets in `.env` files, hardcoding them, or even using separate secret managers per environment creates security risks and operational chaos. Vault provides a unified, audited solution for secret generation, rotation, and access control across all your environments.

## [The Problem](#the-problem)

### [Multi-environment secret chaos](#multi-environment-secret-chaos)

When managing dev, staging, and production environments, secrets management becomes a headache:

-   Different secrets per environment with no central tracking
-   Manual rotation processes prone to human error
-   No audit trail for who accessed which secrets and when
-   Secrets leaking through Git history or logs
-   Difficulty revoking compromised credentials instantly

## [The Solution](#the-solution)

### [HashiCorp Vault overview](#hashicorp-vault-overview)

Vault is a secrets management platform that provides:

-   **Dynamic secrets**: Generate credentials on-demand that auto-expire
-   **Secret rotation**: Automatically rotate credentials without downtime
-   **Audit logging**: Complete trail of all secret access and operations
-   **Environment isolation**: Separate secrets per environment with shared policies
-   **Multi-auth methods**: Support for AppRole, Kubernetes, IAM, JWT, and more

### [TL;DR](#tldr)

-   Use HashiCorp Vault as a centralized secret backend
-   Generate dynamic credentials that auto-expire
-   Implement automatic rotation for long-lived secrets
-   Audit all secret access across environments

## [Installation and setup](#installation-and-setup)

### [Start Vault with Docker](#start-vault-with-docker)

compose.yml

```
services:  vault:    image: vault:latest    container_name: vault    ports:      - "8200:8200"    environment:      VAULT_DEV_ROOT_TOKEN_ID: "root"      VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"    cap_add:      - IPC_LOCK    volumes:      - vault-data:/vault/data    command: server -dev
volumes:  vault-data:
```

Start the Vault server:

Terminal window

```
docker-compose up -dexport VAULT_ADDR='http://localhost:8200'export VAULT_TOKEN='root'
```

## [CLI examples](#cli-examples)

### [Basic secret storage](#basic-secret-storage)

Terminal window

```
# Store a static secretvault kv put secret/dev/database \  username="dbuser" \  password="supersecret" \  host="db.dev.internal"
# Retrieve secretvault kv get secret/dev/database
# Get specific fieldvault kv get -field=password secret/dev/database
```

### [Organize secrets by environment](#organize-secrets-by-environment)

Terminal window

```
# Development secretsvault kv put secret/dev/app-api \  api_key="dev-key-12345" \  api_secret="dev-secret-67890"
# Staging secretsvault kv put secret/staging/app-api \  api_key="staging-key-abcde" \  api_secret="staging-secret-fghij"
# Production secretsvault kv put secret/prod/app-api \  api_key="prod-key-xyz123" \  api_secret="prod-secret-abc456"
```

## [Programming examples](#programming-examples)

### [Python: fetch secrets](#python-fetch-secrets)

fetch\_vault\_secrets.py

```
1import hvac2import os3from typing import Dict, Any4
5class VaultClient:6    def __init__(self, vault_addr: str = "http://localhost:8200", token: str = None):7        self.client = hvac.Client(url=vault_addr, token=token or os.getenv('VAULT_TOKEN'))8
9    def get_secret(self, path: str, field: str = None) -> Dict[str, Any]:10        """Fetch a secret from Vault"""11        response = self.client.secrets.kv.v2.read_secret_version(path=path)12        data = response['data']['data']13
14        if field:15            return data.get(field)16        return data17
18    def get_database_creds(self, environment: str) -> Dict[str, str]:19        """Get database credentials for specific environment"""20        path = f"secret/{environment}/database"21        return self.get_secret(path)22
23    def get_api_keys(self, environment: str) -> Dict[str, str]:24        """Get API keys for specific environment"""25        path = f"secret/{environment}/app-api"26        return self.get_secret(path)27
28# Usage29if __name__ == "__main__":30    vault = VaultClient()31
32    # Get dev database credentials33    db_creds = vault.get_database_creds("dev")34    print(f"Database: {db_creds['host']}")35    print(f"User: {db_creds['username']}")36
37    # Get specific field38    api_key = vault.get_secret("secret/prod/app-api", field="api_key")39    print(f"API Key: {api_key}")
```

### [Node.js: fetch secrets](#nodejs-fetch-secrets)

vaultClient.ts

```
1import * as VaultClient from 'node-vault';2
3class SecretManager {4  private vault: ReturnType<typeof VaultClient>;5
6  constructor(address: string = 'http://localhost:8200', token: string) {7    this.vault = VaultClient({8      apiVersion: 'v1',9      endpoint: address,10      token: token || process.env.VAULT_TOKEN,11    });12  }13
14  async getSecret(path: string, field?: string): Promise<any> {15    try {16      const response = await this.vault.read(path);17      const data = response.data.data;18
19      if (field) {20        return data[field];21      }22      return data;23    } catch (error) {24      console.error(`Failed to retrieve secret from ${path}:`, error);25      throw error;26    }27  }28
29  async getDatabaseConfig(environment: string): Promise<any> {30    return this.getSecret(`secret/${environment}/database`);31  }32
33  async getApiCredentials(environment: string): Promise<any> {34    return this.getSecret(`secret/${environment}/app-api`);35  }36}37
38// Usage39(async () => {40  const manager = new SecretManager('http://localhost:8200', 'root');41
42  const dbConfig = await manager.getDatabaseConfig('dev');43  console.log(`Connecting to: ${dbConfig.host}`);44
45  const apiKey = await manager.getApiCredentials('prod');46  console.log(`API Key: ${apiKey.api_key}`);47})();
```

## [Dynamic database credentials](#dynamic-database-credentials)

### [Configure the database secret engine](#configure-the-database-secret-engine)

Terminal window

```
# Enable database secrets enginevault secrets enable database
# Configure PostgreSQL connectionvault write database/config/postgresql \  plugin_name=postgresql-database-plugin \  allowed_roles="readonly,readwrite" \  connection_url="postgresql://admin:password@db.prod.internal:5432/appdb" \  username="vault_admin" \  password="vault_admin_password"
# Create readonly rolevault write database/roles/readonly \  db_name=postgresql \  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \  default_ttl="1h" \  max_ttl="24h"
# Create readwrite rolevault write database/roles/readwrite \  db_name=postgresql \  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \  default_ttl="6h" \  max_ttl="24h"
```

### [Retrieve dynamic credentials](#retrieve-dynamic-credentials)

Terminal window

```
# Get temporary readonly credentialsvault read database/creds/readonly# Output:# Key                Value# ---                -----# lease_duration     1h# lease_id           database/creds/readonly/...# password           a-temporary-password# username           v-token-readonly-xxxxxxxx
# Get temporary readwrite credentialsvault read database/creds/readwrite
```

### [Python: use dynamic credentials](#python-use-dynamic-credentials)

dynamic\_db\_access.py

```
1import hvac2import psycopg23from typing import Generator4import contextlib5
6class DynamicDatabaseAccess:7    def __init__(self, vault_addr: str, vault_token: str):8        self.vault = hvac.Client(url=vault_addr, token=vault_token)9        self.db_host = os.getenv('DB_HOST', 'db.prod.internal')10        self.db_port = os.getenv('DB_PORT', '5432')11        self.db_name = os.getenv('DB_NAME', 'appdb')12
13    def get_dynamic_credentials(self, role: str) -> dict:14        """Fetch temporary database credentials from Vault"""15        response = self.vault.secrets.database.read_dynamic_credentials(role)16        return response['data']17
18    @contextlib.contextmanager19    def get_connection(self, role: str = 'readonly') -> Generator:20        """Get a database connection with dynamic credentials"""21        creds = self.get_dynamic_credentials(role)22
23        conn = psycopg2.connect(24            host=self.db_host,25            port=self.db_port,26            database=self.db_name,27            user=creds['username'],28            password=creds['password']29        )30
31        try:32            yield conn33        finally:34            conn.close()35
36# Usage37db_access = DynamicDatabaseAccess('http://localhost:8200', 'root')38
39with db_access.get_connection(role='readonly') as conn:40    cursor = conn.cursor()41    cursor.execute("SELECT COUNT(*) FROM users")42    print(f"Total users: {cursor.fetchone()[0]}")
```

## [Policy-based access control](#policy-based-access-control)

### [Create policies for different roles](#create-policies-for-different-roles)

policies/dev-team.hcl

```
1# Read-only access to dev/staging secrets2path "secret/data/dev/*" {3  capabilities = ["read", "list"]4}5
6path "secret/data/staging/*" {7  capabilities = ["read", "list"]8}9
10# Deny access to production11path "secret/data/prod/*" {12  capabilities = ["deny"]13}14
15# Allow token self-renewal16path "auth/token/renew-self" {17  capabilities = ["update"]18}
```

policies/prod-team.hcl

```
1# Full access to production secrets2path "secret/data/prod/*" {3  capabilities = ["create", "read", "update", "delete", "list"]4}5
6# Read-only access to staging7path "secret/data/staging/*" {8  capabilities = ["read", "list"]9}10
11# Database credential access12path "database/creds/prod/*" {13  capabilities = ["read"]14}15
16# Audit logging17path "sys/audit" {18  capabilities = ["read"]19}
```

### [Apply policies](#apply-policies)

Terminal window

```
# Create policiesvault policy write dev-team policies/dev-team.hclvault policy write prod-team policies/prod-team.hcl
# Assign to users/appsvault write auth/userpass/users/jane policies="prod-team"vault write auth/userpass/users/alice policies="dev-team"
```

## [Kubernetes integration](#kubernetes-integration)

### [Enable Kubernetes auth](#enable-kubernetes-auth)

Terminal window

```
# Enable Kubernetes authenticationvault auth enable kubernetes
# Configure Kubernetes authvault write auth/kubernetes/config \  token_reviewer_jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token \  kubernetes_host="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT" \  kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# Create role for podsvault write auth/kubernetes/role/app-role \  bound_service_account_names=app \  bound_service_account_namespaces=default \  policies=default,app-secrets \  ttl=24h
```

### [Pod configuration](#pod-configuration)

kubernetes-deployment.yaml

```
1apiVersion: apps/v12kind: Deployment3metadata:4  name: app5spec:6  replicas: 27  selector:8    matchLabels:9      app: myapp10  template:11    metadata:12      labels:13        app: myapp14    spec:15      serviceAccountName: app16      containers:17        - name: myapp18          image: myapp:latest19          env:20            - name: VAULT_ADDR21              value: 'http://vault.vault.svc.cluster.local:8200'22            - name: VAULT_SKIP_VERIFY23              value: 'false'24          volumeMounts:25            - name: vault-token26              mountPath: /vault/secrets27      volumes:28        - name: vault-token29          projected:30            sources:31              - serviceAccountToken:32                  audience: vault33                  expirationSeconds: 360034                  path: token
```

## [Audit logging](#audit-logging)

### [Enable audit logging](#enable-audit-logging)

Terminal window

```
# Enable file audit backendvault audit enable file file_path=/vault/logs/audit.log
# Enable syslog audit backendvault audit enable syslog tag="vault"
# View audit logstail -f /vault/logs/audit.log | jq '.'
```

### [Query audit logs](#query-audit-logs)

Terminal window

```
# Show all secret readscat /vault/logs/audit.log | jq 'select(.type == "response" and .auth.policy_results.granted_policies >= 0)'
# Show secret modificationscat /vault/logs/audit.log | jq 'select(.type == "request" and .request.operation == "write")'
# Show failed auth attemptscat /vault/logs/audit.log | jq 'select(.response.auth == null)'
```

## [Best practices](#best-practices)

### [1\. Use AppRole for applications](#1-use-approle-for-applications)

Terminal window

```
# Create AppRolevault auth enable approle
# Generate application rolevault write auth/approle/role/my-app \  token_ttl=1h \  token_max_ttl=4h \  policies="app-secrets"
# Get role IDvault read auth/approle/role/my-app/role-id
# Generate secret IDvault write -f auth/approle/role/my-app/secret-id
```

### [2\. Rotate secrets regularly](#2-rotate-secrets-regularly)

Terminal window

```
# Configure auto-rotation every 30 daysvault write database/config/postgresql \  connection_url="postgresql://admin:password@db.prod.internal:5432/appdb" \  rotation_statements="ALTER ROLE \"{{name}}\" WITH PASSWORD '{{password}}';" \  rotation_period=720h
```

### [3\. Implement least privilege](#3-implement-least-privilege)

```
1# Only grant necessary capabilities2path "secret/data/myapp/*" {3  capabilities = ["read"]  # Not "update" or "delete"4}
```

## [Resources](#resources)

-   [HashiCorp Vault Documentation](https://www.vaultproject.io/docs)
-   [Vault API Reference](https://www.vaultproject.io/api-docs)
-   [hvac Python Client](https://github.com/hvac/hvac)
-   [node-vault NPM Package](https://github.com/hashicorp/node-vault)

Was this useful?

## Tags

[#Vault](/codesnippets/tags/vault)[#SecretsManagement](/codesnippets/tags/secretsmanagement)[#MultiEnvironment](/codesnippets/tags/multienvironment)[#Security](/codesnippets/tags/security)[#DevOps](/codesnippets/tags/devops)[#IAM](/codesnippets/tags/iam)

## Share

[Facebook](https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets "Share on Facebook")[Twitter](https://twitter.com/intent/tweet/?text=Multi-Environment%20Secret%20Management%20with%20HashiCorp%20Vault&url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets "Share on Twitter")[LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets&title=Multi-Environment%20Secret%20Management%20with%20HashiCorp%20Vault&summary=Manage%20secrets%20securely%20across%20dev%2C%20staging%2C%20and%20production%20with%20HashiCorp%20Vault.%20This%20snippet%20demonstrates%20dynamic%20secret%20generation%2C%20rotation%2C%20and%20cross-environment%20secret%20syncing%20patterns.&source=https://mkabumattar.com "Share on LinkedIn")[WhatsApp](https://wa.me/?text=Multi-Environment%20Secret%20Management%20with%20HashiCorp%20Vault%20https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets "Share on WhatsApp")[Telegram](https://t.me/share/url?url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets&text=Multi-Environment%20Secret%20Management%20with%20HashiCorp%20Vault "Share on Telegram")[Reddit](https://www.reddit.com/submit?url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets&title=Multi-Environment%20Secret%20Management%20with%20HashiCorp%20Vault "Share on Reddit")[Hacker News](http://news.ycombinator.com/submitlink?u=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets&t=Multi-Environment%20Secret%20Management%20with%20HashiCorp%20Vault "Share on Hacker News")[Pinterest](https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets&media=&description=Manage%20secrets%20securely%20across%20dev%2C%20staging%2C%20and%20production%20with%20HashiCorp%20Vault.%20This%20snippet%20demonstrates%20dynamic%20secret%20generation%2C%20rotation%2C%20and%20cross-environment%20secret%20syncing%20patterns. "Share on Pinterest")[Email](<mailto:?subject=Multi-Environment%20Secret%20Management%20with%20HashiCorp%20Vault&body=Check out this article: https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fhashicorp-vault-multi-environment-secrets>)

## Comments

## You might also enjoy

More posts on similar topics

[![AWS EC2 Instance Management with Boto3: Start, Stop, and Query Instances](/_astro/hero.PnHlvJay_ZkFqWG.webp)](/codesnippets/post/aws-ec2-instance-management-boto3-python)

## [AWS EC2 Instance Management with Boto3: Start, Stop, and Query Instances](/codesnippets/post/aws-ec2-instance-management-boto3-python)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Cloud](/codesnippets/categories/cloud)
-   [Aws](/codesnippets/categories/aws)
-   [Devops](/codesnippets/categories/devops)
-   [Automation](/codesnippets/categories/automation)

If you've ever spent 20 minutes clicking through the AWS Console just to stop a handful of dev instances, you already know the pain. It's tedious, it doesn't scale, and one wrong click can ruin your a

[#AWS](/codesnippets/tags/aws)[#EC2](/codesnippets/tags/ec2)[#Boto3](/codesnippets/tags/boto3)+6 tags

[read more](/codesnippets/post/aws-ec2-instance-management-boto3-python)

[![Essential Bash Variables for Every Script](/_astro/hero.B4bDowyY_YQpD7.webp)](/codesnippets/post/essential-bash-variables)

## [Essential Bash Variables for Every Script](/codesnippets/post/essential-bash-variables)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Shell scripting](/codesnippets/categories/shell-scripting)
-   [Devops](/codesnippets/categories/devops)

Overview Quick Tip You know what's worse than writing scripts? Writing scripts that break every time you move them to a different machine. Built-in Bash variables fix that. The problem wi

[#Bash](/codesnippets/tags/bash)[#Shell Scripting](/codesnippets/tags/shell-scripting)[#Linux](/codesnippets/tags/linux)+4 tags

[read more](/codesnippets/post/essential-bash-variables)

[![Bash Retry Function: Automatically Retry Failing Commands with Exponential Backoff](/_astro/hero.Dap62rVN_Z1q0nar.webp)](/codesnippets/post/bash-retry-function-exponential-backoff)

## [Bash Retry Function: Automatically Retry Failing Commands with Exponential Backoff](/codesnippets/post/bash-retry-function-exponential-backoff)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Devops](/codesnippets/categories/devops)
-   [Shell scripting](/codesnippets/categories/shell-scripting)
-   [Automation](/codesnippets/categories/automation)

Quick Tip Wrap any flaky command in one reusable retry function and stop re-running red pipelines by hand. The Problem The Problem Some commands fail for reasons that have nothing to

[#Bash](/codesnippets/tags/bash)[#Retry](/codesnippets/tags/retry)[#Exponential Backoff](/codesnippets/tags/exponential-backoff)+3 tags

[read more](/codesnippets/post/bash-retry-function-exponential-backoff)

[![Check S3 Bucket Existence](/_astro/hero.CWiO4GWV_1YUYTb.webp)](/codesnippets/post/bash-s3-bucket-exists)

## [Check S3 Bucket Existence](/codesnippets/post/bash-s3-bucket-exists)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Aws](/codesnippets/categories/aws)
-   [Shell scripting](/codesnippets/categories/shell-scripting)
-   [Devops](/codesnippets/categories/devops)

Quick Tip Don't let your deployment blow up because of a missing S3 bucket. This Bash script lets you check if a bucket exists before anything fails. The Problem Missing bucket failure

[#Bash](/codesnippets/tags/bash)[#AWS](/codesnippets/tags/aws)[#DevOps](/codesnippets/tags/devops)+3 tags

[read more](/codesnippets/post/bash-s3-bucket-exists)

[![AWS Secrets Manager](/_astro/hero.BIDl4oI2_Z1yJEXf.webp)](/codesnippets/post/nodejs-aws-secrets-manager)

## [AWS Secrets Manager](/codesnippets/post/nodejs-aws-secrets-manager)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Aws](/codesnippets/categories/aws)
-   [Devops](/codesnippets/categories/devops)

Loading secrets in a Node.js app without exposing them If you're still storing API keys or database credentials in .env files or hardcoding them into your codebase, it's time for a better appro

[#NodeJS](/codesnippets/tags/nodejs)[#TypeScript](/codesnippets/tags/typescript)[#AWS](/codesnippets/tags/aws)+3 tags

[read more](/codesnippets/post/nodejs-aws-secrets-manager)

[![List S3 Buckets](/_astro/hero.BsiJ6hry_1X9XLn.webp)](/codesnippets/post/python-list-s3-buckets)

## [List S3 Buckets](/codesnippets/post/python-list-s3-buckets)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Aws](/codesnippets/categories/aws)
-   [Python](/codesnippets/categories/python)
-   [Devops](/codesnippets/categories/devops)

Overview Multi-profile S3 management Ever juggled multiple AWS accounts and needed a quick S3 bucket inventory across all of them? This Python script handles it. Use case Perfect for or

[#Python](/codesnippets/tags/python)[#Boto3](/codesnippets/tags/boto3)[#AWS](/codesnippets/tags/aws)+5 tags

[read more](/codesnippets/post/python-list-s3-buckets)

6 related posts
