<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged localstack</title>
<link>https://coderlegion.com/tag/localstack</link>
<description>Powered by Question2Answer</description>
<item>
<title>How I run LocalStack without committing LOCALSTACK_AUTH_TOKEN</title>
<link>https://coderlegion.com/20078/how-i-run-localstack-without-committing-localstackauthtoken</link>
<description>&lt;h3 id=&quot;using-envilder-to-keep-the-localstack-auth-token-out-of-git-while-preserving-a-reproducible-local-docker-compose-setup-&quot;&gt;&lt;em&gt;Using &lt;a rel=&quot;nofollow&quot; href=&quot;https://envilder.com/&quot;&gt;Envilder&lt;/a&gt; to keep the LocalStack auth token out of Git while preserving a reproducible local Docker Compose setup.&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;I wanted a reproducible LocalStack setup without committing &lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt; to the repository.&lt;/p&gt;
&lt;p&gt;That sounds simple, but it touches a common local development problem:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;How do you make a project easy to run without putting real secrets in Git?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;LocalStack &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.localstack.cloud/aws/getting-started/auth-token/&quot;&gt;expects the auth token&lt;/a&gt; to be available through the &lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt; environment variable when starting it with Docker, Docker Compose, the LocalStack CLI, or CI workflows.&lt;/p&gt;
&lt;p&gt;Since &lt;a rel=&quot;nofollow&quot; href=&quot;https://blog.localstack.cloud/localstack-for-aws-release-2026-03-0/&quot;&gt;LocalStack for AWS 2026.03.0&lt;/a&gt;, it ships as a consolidated Docker image and requires an auth token to start, so managing &lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt; cleanly is now part of the normal setup path, not just a Pro-only edge case.&lt;/p&gt;
&lt;p&gt;That token is a secret, so I did not want to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;commit it to the repository&lt;/li&gt;
&lt;li&gt;paste it into &lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;duplicate it across helper scripts&lt;/li&gt;
&lt;li&gt;rely on a manual &lt;code&gt;export LOCALSTACK_AUTH_TOKEN=...&lt;/code&gt; step every time&lt;/li&gt;
&lt;li&gt;make the setup work only on my machine&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What I wanted instead was a small, repeatable contract:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;this project needs LOCALSTACK_AUTH_TOKEN
resolve it from the secret store
inject it locally when needed
do not commit the value
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the pattern I ended up using with &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/macalbert/envilder&quot;&gt;Envilder&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-pattern&quot;&gt;The Pattern&lt;/h3&gt;
&lt;p&gt;The idea is simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;secret values stay in a real secret store&lt;/li&gt;
&lt;li&gt;the repository contains only the mapping&lt;/li&gt;
&lt;li&gt;local development generates a &lt;code&gt;.env&lt;/code&gt; file from that mapping&lt;/li&gt;
&lt;li&gt;Docker Compose reads the generated &lt;code&gt;.env&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the token never gets committed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this case, the secret is &lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In another project, it could be a database password, webhook secret, API key, or service credential.&lt;/p&gt;
&lt;h3 id=&quot;defining-the-secret-mapping&quot;&gt;Defining the Secret Mapping&lt;/h3&gt;
&lt;p&gt;Here is a minimal &lt;code&gt;envilder.json&lt;/code&gt; example using AWS SSM Parameter Store:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;$schema&quot;: &quot;https://envilder.com/schema/map-file.v1.json&quot;,
  &quot;$config&quot;: {
    &quot;provider&quot;: &quot;aws&quot;,
    &quot;profile&quot;: &quot;default&quot;
  },
  &quot;LOCALSTACK_AUTH_TOKEN&quot;: &quot;/envilder/localstack/auth-token&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This file is safe to commit because it does not contain the token.&lt;/p&gt;
&lt;p&gt;It only says:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;_To produce &lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt;, resolve this value from the secret store._&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The actual token remains outside the repository.&lt;/p&gt;
&lt;h3 id=&quot;generating-the-local-env&quot;&gt;Generating the Local &lt;code&gt;.env&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Before starting LocalStack, generate the local environment file:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx envilder --map=envilder.json --envfile=.env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That produces a local &lt;code&gt;.env&lt;/code&gt; file like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-env&quot;&gt;LOCALSTACK_AUTH_TOKEN=...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;.env&lt;/code&gt; file should be ignored by Git:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-gitignore&quot;&gt;.env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the project contains the setup contract, but not the secret.&lt;/p&gt;
&lt;h3 id=&quot;passing-the-token-to-localstack&quot;&gt;Passing the Token to LocalStack&lt;/h3&gt;
&lt;p&gt;A Docker Compose service can reference the variable as usual:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  localstack:
    image: localstack/localstack:stable
    ports:
      - &quot;4566:4566&quot;
      - &quot;4510-4559:4510-4559&quot;
    environment:
      LOCALSTACK_AUTH_TOKEN: \$&quot;{LOCALSTACK_AUTH_TOKEN:?Run npx envilder first}&quot;
    volumes:
      - &quot;/var/run/docker.sock:/var/run/docker.sock&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Docker Compose automatically reads a &lt;code&gt;.env&lt;/code&gt; file from the project directory for variable interpolation.&lt;/p&gt;
&lt;p&gt;If your generated env file lives somewhere else, you can pass it explicitly:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker compose --env-file path/to/.env up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The payoff is what a new contributor sees after cloning:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx envilder --map=envilder.json --envfile=.env
docker compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Two commands, no Slack message asking &quot;where do I get the token?&quot;, no secret in Git.&lt;/p&gt;
&lt;h3 id=&quot;why-not-direnv-1password-or-chamber-&quot;&gt;Why not direnv, 1Password, or chamber?&lt;/h3&gt;
&lt;p&gt;For one developer, &lt;code&gt;export LOCALSTACK_AUTH_TOKEN=...&lt;/code&gt; works, but it creates hidden local state the repo never documents. The interesting comparison is against the tools that already resolve secrets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;direnv&lt;/strong&gt; loads env vars when you enter a directory, but &lt;code&gt;.envrc&lt;/code&gt; is just shell. You still write &lt;code&gt;export LOCALSTACK_AUTH_TOKEN=$(aws ssm get-parameter ...)&lt;/code&gt; yourself, per variable, per project. It is a loader, not a resolver, and the mapping lives in bespoke shell instead of a declared contract.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1Password &lt;code&gt;op run&lt;/code&gt;&lt;/strong&gt; injects secrets at runtime and is excellent, but it assumes 1Password is your store. If your secrets already live in AWS SSM or Azure Key Vault, you are adding a vendor, not removing one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;chamber&lt;/strong&gt; is the closest match for the AWS-only case:&lt;br&gt;
&lt;code&gt;chamber exec service -- docker compose up&lt;/code&gt; reads straight from SSM. If you never leave AWS and only need secrets at the command line, chamber or a three-line script is genuinely enough.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Envilder's narrow bet is different on three points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The mapping is an explicit &lt;code&gt;name -&amp;gt; path&lt;/code&gt; contract committed as JSON, not a service prefix or shell glue.&lt;/li&gt;
&lt;li&gt;The store is your own cloud. No third-party infrastructure holds the secret.&lt;/li&gt;
&lt;li&gt;The same map drives the CLI here, CI, and in-process resolution through the SDKs, so local dev and runtime read one contract.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you only ever touch AWS from a shell, you may not need it. The case shows up when you have more than one provider, more than one language, or want the same declared contract locally, in CI, and at runtime.&lt;/p&gt;
&lt;h3 id=&quot;the-slightly-meta-part&quot;&gt;The Slightly Meta Part&lt;/h3&gt;
&lt;p&gt;I ran into this while working on Envilder.&lt;/p&gt;
&lt;p&gt;Envilder uses LocalStack for integration testing.&lt;/p&gt;
&lt;p&gt;LocalStack needs &lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So I used Envilder to inject the token needed to start the LocalStack environment used to test Envilder.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tfkdag8d7ske6xb59ta.png&quot; alt=&quot;Envilder uses Envilder to inject LocalStack token&quot;&gt;&lt;/p&gt;
&lt;p&gt;The tool became its own first customer, which is always a useful kind of feedback.&lt;/p&gt;
&lt;h3 id=&quot;a-note-on-localstack-auth-tokens&quot;&gt;A Note on LocalStack Auth Tokens&lt;/h3&gt;
&lt;p&gt;LocalStack's documentation is clear that &lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt; should be kept confidential and should not be committed to source control.&lt;/p&gt;
&lt;p&gt;This post is not about bypassing that requirement.&lt;/p&gt;
&lt;p&gt;It is about treating the token like any other secret:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;store it safely&lt;/li&gt;
&lt;li&gt;resolve it when needed&lt;/li&gt;
&lt;li&gt;avoid leaking it into Git&lt;/li&gt;
&lt;li&gt;keep the project setup reproducible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For open source maintainers, this matters. A project can require credentials for local or CI workflows and still provide a clean setup path for contributors.&lt;/p&gt;
&lt;h3 id=&quot;takeaway&quot;&gt;Takeaway&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;LOCALSTACK_AUTH_TOKEN&lt;/code&gt; is just one example of a broader problem.&lt;/p&gt;
&lt;p&gt;Projects often need secrets during local development, CI/CD, tests, and runtime. The hard part is not only storing those secrets safely. It is keeping the mapping between &quot;what the app needs&quot; and &quot;where the secret lives&quot; clear and consistent.&lt;/p&gt;
&lt;p&gt;The pattern I like is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;secret values outside Git
secret mappings inside Git
one contract for local dev, CI/CD, and runtime
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the reason I am building Envilder.&lt;/p&gt;
&lt;p&gt;Not to add another place to store secrets.&lt;/p&gt;
&lt;p&gt;Just to make secret resolution explicit, repeatable, and versionable.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/20078/how-i-run-localstack-without-committing-localstackauthtoken</guid>
<pubDate>Tue, 09 Jun 2026 14:51:24 +0000</pubDate>
</item>
</channel>
</rss>