Storing secrets as code involves various methods, including encrypting secrets in Git repositories, managing them through Infrastructure as Code (IaC), or injecting them dynamically at runtime, each with its strengths and drawbacks. The most secure approach centralizes secrets in a manager, minimizes their presence in Git, fetches them only when needed, and ensures access is tightly scoped and regularly rotated. While storing encrypted secrets in Git can suit GitOps-first teams, it risks operational overhead and potential exposure if not managed diligently. On the other hand, IaC solutions integrate well with compliance processes but depend heavily on secrets manager uptime. Dynamic runtime injection offers the highest security by limiting secret exposure and enabling automatic rotation, making it ideal for fast-moving or security-focused teams. Regardless of the chosen method, it's crucial to avoid common pitfalls such as encoding instead of encrypting, embedding secrets in build artifacts, and using broad, non-rotated tokens. Implementing secrets as code effectively requires a centralized management system, runtime fetching, strict access controls, and a robust rotation policy to ensure security and scalability.