incompass/aws-secrets-bundle
A Symfony bundle that integrates AWS Secrets Manager, letting you load and manage secrets from AWS directly in your application configuration and environment without hardcoding sensitive values.
The build-vs-buy-vs-fork call. The capability here is narrow: at boot, fetch a JSON secret from AWS Secrets Manager and merge it into the environment so existing config code resolves without changes. That is a few hundred lines, not a platform. This package is best framed as a reference implementation for a decision, not a product to adopt. PM decision: do we own a small internal loader, or take a dependency on unmaintained code that sits on the credentials path? The answer is almost always "own it."
Security and compliance gating. Removing plaintext credentials from .env files, CI variables, and repo history closes a standard finding in SOC 2 / ISO 27001 reviews and enterprise security questionnaires. If a deal or a security review is blocked on "secrets are stored in source control," this is the cheapest path to checkbox closure. That framing — compliance gate, not feature — is what gets it funded.
A Laravel-specific architecture decision the PM has to force. Despite the description, this artifact is a Symfony bundle, not a Laravel package. That changes the product decision from "should we install this?" to "which Laravel-native mechanism do we standardize on?" Options: a maintained secrets loader, Laravel Vapor's first-party integration, or an in-house service provider. The PM's job is to pick one and prevent three teams from picking three different ones. Critically, any solution must run before config:cache — after caching, env() outside config files returns null, and teams discover this in production.
Environment parity and configuration contract. Adoption lets prod, staging, and local share the same config keys while resolving from different sources (Secrets Manager in prod, .env locally). This shapes how many environments you can afford to run, how much config drift you tolerate, and whether preview environments are viable.
Rotation as a roadmap commitment, not a slogan. Secrets Manager does not push rotations to running apps. Whatever cache TTL the loader uses defines your exposure window after a credential rotates. Committing to automated credential rotation means committing to an explicit, documented TTL and a propagation window — a real roadmap constraint that should be written down, not assumed.
Multi-tenant scoping and blast radius. Deciding whether secrets are namespaced per tenant, per service, or per stage determines isolation guarantees you can make in architecture docs, pricing tiers for enterprise customers, and how far a single leaked credential reaches.
Cloud standardization — made visible. Choosing this quietly commits you to AWS-native, IAM-first infrastructure. That may already be the platform decision; the PM's value-add is naming it as a lock-in consideration instead of letting it happen by default.
Worth a spike (as a reference, not a dependency) when:
.env fallback for local development is acceptable.Look elsewhere when:
For executives. This is a small, cheap piece of plumbing that lets us stop storing database passwords and API keys in plaintext across our repos and CI. It closes a standard finding in security reviews and enterprise procurement questionnaires, and it makes credential rotation possible without redeploys. The important caveat is that the package itself is a Symfony bundle with zero adoption and no maintainer — and we run Laravel. So the recommendation is not to buy or adopt anything. It is a two-to-three day spike to confirm the pattern, followed by a decision to either vendor the code into our own repository or write the equivalent in-house. Either way we own it, which is appropriate for something this small and this sensitive. Cost is roughly one engineer-week and near-zero recurring AWS spend, since the fetch happens at boot.
For engineering. The pattern is right: at application boot, before config is cached and before the container compiles, call GetSecretValue once and merge the JSON into the environment so existing env() calls resolve to managed values. Our integration is small — a Laravel service provider hooked into the bootstrap path, a scoped IAM policy (one secret ARN, GetSecretValue, plus kms:Decrypt on the specific CMK, no wildcards), and a disable flag so local development and CI never touch AWS. Three things to verify before we commit: (1) failure mode — if Secrets Manager, KMS, or STS is unreachable or the role drifts, we must fail loudly at boot, never silently fall back to stale or empty values; (2) caching — an uncached boot is a network call, so we need an explicit TTL, and that TTL is our rotation propagation window; (3) secret hygiene — loading values into $_ENV exposes them to debug toolbars, error pages, and logging middleware, so redaction needs to be confirmed. Rollout is staged: create the secret, enable the loader in staging in non-authoritative mode (remote values loaded, existing env still wins), diff the value sets for a week, then flip staging and production one service at a time, keeping a stripped .env as a rollback lever for one release cycle before scrubbing ciphertext from CI and image layers.
Ask. Approve the spike and the fork-and-own decision, including an owner on the platform team and a quarterly review of SDK/PHP compatibility. Do not approve this package as a long-term external dependency on the credentials path — and do not let it be adopted as-is into a Laravel codebase.
How can I help you explore Laravel packages today?