<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Titan Ron</title>
    <description>The latest articles on DEV Community by Titan Ron (@titanron).</description>
    <link>https://dev.to/titanron</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1402364%2F7a9eb8f2-edbf-4589-afce-0d28de1c79b8.jpeg</url>
      <title>DEV Community: Titan Ron</title>
      <link>https://dev.to/titanron</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/titanron"/>
    <language>en</language>
    <item>
      <title>A new Git worktree shouldn’t mean another copy of your secrets</title>
      <dc:creator>Titan Ron</dc:creator>
      <pubDate>Tue, 27 Oct 2026 20:32:51 +0000</pubDate>
      <link>https://dev.to/titanron/a-new-git-worktree-shouldnt-mean-another-copy-of-your-secrets-424</link>
      <guid>https://dev.to/titanron/a-new-git-worktree-shouldnt-mean-another-copy-of-your-secrets-424</guid>
      <description>&lt;p&gt;Git worktrees let you keep several branches checked out at once, each in its own directory. Getting your application running in each directory can still involve some manual work.&lt;/p&gt;

&lt;p&gt;You create a worktree, install dependencies, and start the app. It fails because the ignored &lt;code&gt;.env&lt;/code&gt; file stayed behind in the other checkout.&lt;/p&gt;

&lt;p&gt;You can copy the file, create a symlink, or run a script to download the values. Each approach can work, but it adds something to maintain. Copying plaintext secrets also creates more files to keep current when those values change.&lt;/p&gt;

&lt;p&gt;I’m building &lt;a href="https://github.com/ciqol/resenv" rel="noopener noreferrer"&gt;resenv&lt;/a&gt; to simplify this part of the workflow: keep references in project configuration and resolve their values when the application starts.&lt;/p&gt;

&lt;p&gt;For Node and Nx projects using Doppler, a reference looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API_TOKEN=doppler://my-project/dev/API_TOKEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It identifies the project, configuration, and secret to retrieve. The reference itself grants no access. The authenticated developer still needs permission to read that secret.&lt;/p&gt;

&lt;p&gt;At startup, resenv fetches the value and replaces the reference in the application’s environment before application imports execute. Your code continues to read &lt;code&gt;process.env.API_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the references available in every worktree
&lt;/h2&gt;

&lt;p&gt;Putting references in an ignored &lt;code&gt;.env&lt;/code&gt; file removes plaintext values from that file, but the file would still be missing from a new worktree.&lt;/p&gt;

&lt;p&gt;To remove that setup step, the reference configuration needs to travel with the project.&lt;/p&gt;

&lt;p&gt;Here’s an example using an Nx target. It assumes the application’s entry point is &lt;code&gt;app.mjs&lt;/code&gt; inside its project directory.&lt;/p&gt;

&lt;p&gt;Install resenv:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-exact&lt;/span&gt; @ciqol/resenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure authentication using the &lt;a href="https://github.com/ciqol/resenv/blob/beta/docs/doppler.md" rel="noopener noreferrer"&gt;Doppler setup guide&lt;/a&gt;. Supported methods include an explicit token, resenv’s OS credential storage, and existing Doppler CLI credentials. The guide covers platform support and current login limitations.&lt;/p&gt;

&lt;p&gt;Then configure the application target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nx:run-commands"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cache"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"continuous"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{projectRoot}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node --import @ciqol/resenv/resolve app.mjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"API_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"doppler://my-project/dev/API_TOKEN"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This target contains a reference rather than a credential. Project and secret names can still reveal configuration details, so review whether those names are appropriate to include in your repository.&lt;/p&gt;

&lt;p&gt;Run the target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--no-install&lt;/span&gt; nx serve api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nx supplies the environment to the application process. The resenv preload resolves the reference before the application starts.&lt;/p&gt;

&lt;p&gt;With this configuration available alongside the code, another worktree receives the same reference and startup command. You still install dependencies and complete the application’s usual setup, but you don’t need another plaintext copy of &lt;code&gt;API_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep your existing environment loading
&lt;/h2&gt;

&lt;p&gt;resenv resolves values already present in the environment. Your existing loader remains responsible for selecting and loading configuration files.&lt;/p&gt;

&lt;p&gt;In the example above, the reference is explicitly supplied through the target’s &lt;code&gt;env&lt;/code&gt; option, which &lt;a href="https://nx.dev/docs/reference/nx/executors" rel="noopener noreferrer"&gt;Nx gives precedence over dotenv files&lt;/a&gt;. If you prefer file-based overrides, references can live in the files your loader selects instead. Those files still need to be provisioned in each worktree.&lt;/p&gt;

&lt;p&gt;The preload belongs on the application process, after its environment has been loaded. Preloading the outer Nx process would run too early.&lt;/p&gt;

&lt;p&gt;Each reference explicitly selects its Doppler project and configuration. Worktrees can use the same references or different ones where needed; resenv doesn’t choose a configuration from the branch name.&lt;/p&gt;

&lt;p&gt;Resolution happens once at startup. Restart the application to fetch updated values. If a required lookup fails, startup stops before resenv applies replacements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this fits among the alternatives
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.doppler.com/docs/secrets-setup-guide" rel="noopener noreferrer"&gt;Doppler CLI&lt;/a&gt; already supports injecting secrets for a selected project and configuration. &lt;a href="https://developer.1password.com/docs/cli/secrets-scripts" rel="noopener noreferrer"&gt;1Password CLI&lt;/a&gt; supports resolving secret references at runtime too.&lt;/p&gt;

&lt;p&gt;resenv focuses on resolving individual Doppler references within the environment your Node application already receives. That includes Nx’s existing loading flow and references pointing to different Doppler projects or configurations.&lt;/p&gt;

&lt;p&gt;The benefit I’m trying to validate is less setup when moving between worktrees, while keeping the application’s environment-loading conventions.&lt;/p&gt;

&lt;h2&gt;
  
  
  A specific security benefit
&lt;/h2&gt;

&lt;p&gt;resenv doesn’t write fetched values back into dotenv files or cache those values on disk. This reduces the need to maintain plaintext secret files in working directories.&lt;/p&gt;

&lt;p&gt;Your application still receives the resolved secrets. resenv doesn’t isolate worktrees or programs running with access to the same credentials. Doppler permissions remain the authorization boundary.&lt;/p&gt;

&lt;p&gt;resenv is available as an &lt;strong&gt;experimental beta&lt;/strong&gt;. It currently supports Doppler as its only built-in cloud provider, requires Node.js 20 or later, and has no runtime npm dependencies.&lt;/p&gt;

&lt;p&gt;I’m looking for feedback from developers working across multiple Git worktrees:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you make secrets available in a fresh worktree today, and which part of that setup would you most like to remove?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ciqol/resenv" rel="noopener noreferrer"&gt;Source and setup instructions&lt;/a&gt; · &lt;a href="https://github.com/ciqol/resenv/issues" rel="noopener noreferrer"&gt;Share feedback&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>node</category>
      <category>security</category>
      <category>showdev</category>
    </item>
    <item>
      <title>What Karate Taught Me About Engineering Leadership</title>
      <dc:creator>Titan Ron</dc:creator>
      <pubDate>Wed, 24 Jun 2026 22:27:57 +0000</pubDate>
      <link>https://dev.to/titanron/what-karate-taught-me-about-engineering-leadership-3hp9</link>
      <guid>https://dev.to/titanron/what-karate-taught-me-about-engineering-leadership-3hp9</guid>
      <description>&lt;p&gt;I recently published a personal reflection about something I did not expect to connect so strongly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Karate and engineering leadership.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As of writing the article, I have practiced karate for more than 20 years. For a long time, karate was karate, and work was work.&lt;/p&gt;

&lt;p&gt;But over time, especially around architecture, migrations, incidents, and team leadership, I started seeing the overlap.&lt;/p&gt;

&lt;p&gt;A few ideas from the article:&lt;/p&gt;

&lt;h2&gt;
  
  
  Pressure reveals training
&lt;/h2&gt;

&lt;p&gt;In engineering, incidents and migrations do not usually create the real gaps.&lt;/p&gt;

&lt;p&gt;They reveal them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ownership gaps&lt;/li&gt;
&lt;li&gt;Missing context&lt;/li&gt;
&lt;li&gt;Hidden assumptions&lt;/li&gt;
&lt;li&gt;Unclear flows&lt;/li&gt;
&lt;li&gt;Places where people are afraid to say “I don’t know”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That reminded me a lot of training.&lt;/p&gt;

&lt;p&gt;Under pressure, you do not always get to choose how you react. You fall back to what was actually practiced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplicity is not shallow
&lt;/h2&gt;

&lt;p&gt;In karate, a basic movement can look simple from the outside.&lt;/p&gt;

&lt;p&gt;But after years of practice, you realize that simple does not mean easy.&lt;/p&gt;

&lt;p&gt;I think good architecture is similar.&lt;/p&gt;

&lt;p&gt;The best architecture is not always the most advanced one. Sometimes it is the one people can actually understand, operate, and improve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Always be a student
&lt;/h2&gt;

&lt;p&gt;One sentence my sensei often says stayed with me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;תמיד תהיה תלמיד&lt;br&gt;&lt;br&gt;
Always be a student.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For me, this became a leadership lesson.&lt;/p&gt;

&lt;p&gt;Being responsible for something does not mean pretending to know everything.&lt;/p&gt;

&lt;p&gt;It means caring enough to keep learning.&lt;/p&gt;

&lt;p&gt;And it also means creating enough trust so others can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I do not know.&lt;br&gt;&lt;br&gt;
I am missing context.&lt;br&gt;&lt;br&gt;
I need help connecting the dots.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because if I do not know what is missing, I cannot help.&lt;/p&gt;

&lt;h2&gt;
  
  
  The full article
&lt;/h2&gt;

&lt;p&gt;I wrote the full reflection here:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://medium.com/@titan-ron/what-20-years-of-karate-taught-me-about-leadership-0ed3399b749c" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;medium.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Would love to hear how other engineers think about this.&lt;/p&gt;

&lt;p&gt;What is something outside of software that shaped the way you write code, lead teams, or think about systems?&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>softwareengineering</category>
      <category>career</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
