<?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>Forem: Ayomide Adebisi</title>
    <description>The latest articles on Forem by Ayomide Adebisi (@alsaheem).</description>
    <link>https://forem.com/alsaheem</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F248120%2F94fa93c9-e676-4daa-8e7f-b94e4c20a006.png</url>
      <title>Forem: Ayomide Adebisi</title>
      <link>https://forem.com/alsaheem</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alsaheem"/>
    <language>en</language>
    <item>
      <title>How to Store Secrets in the Mac Keychain (and Use Them Like Environment Variables)</title>
      <dc:creator>Ayomide Adebisi</dc:creator>
      <pubDate>Sat, 28 Mar 2026 17:27:11 +0000</pubDate>
      <link>https://forem.com/alsaheem/how-to-store-secrets-in-the-mac-keychain-and-use-them-like-environment-variables-1aj7</link>
      <guid>https://forem.com/alsaheem/how-to-store-secrets-in-the-mac-keychain-and-use-them-like-environment-variables-1aj7</guid>
      <description>&lt;p&gt;I used to keep API keys in &lt;code&gt;.env&lt;/code&gt; because it was fast. Then I caught myself grepping my home folder for something unrelated and watching paths scroll past that file, or almost committing a backup copy. None of that is catastrophic every time, but it’s a bad habit. On a Mac you already have a place meant for secrets: &lt;strong&gt;Keychain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This isn’t a pitch for a fancy secrets vault. It’s about the &lt;strong&gt;security&lt;/strong&gt; tool that ships with macOS—handy for &lt;strong&gt;local dev&lt;/strong&gt; tokens, DB URLs, signing keys, that sort of thing.&lt;/p&gt;

&lt;p&gt;One thing to get straight up front: Keychain doesn’t literally store “environment variables.” It stores &lt;strong&gt;items&lt;/strong&gt; (usually generic passwords) keyed by &lt;strong&gt;service name&lt;/strong&gt; and &lt;strong&gt;account&lt;/strong&gt;. You &lt;strong&gt;pull the value out&lt;/strong&gt; with &lt;code&gt;security&lt;/code&gt; and &lt;strong&gt;&lt;code&gt;export&lt;/code&gt;&lt;/strong&gt; it when you need it. Day to day it behaves like env vars; under the hood it’s a lookup, not a magic &lt;code&gt;.env&lt;/code&gt; replacement.&lt;/p&gt;

&lt;p&gt;You’ll need a Mac, a terminal, and if you want secrets to load automatically, willingness to touch &lt;code&gt;~/.zshrc&lt;/code&gt; or similar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Save and read a secret
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Add&lt;/strong&gt; a generic password (Terminal may ask for Keychain permission the first time):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;security add-generic-password &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"myapp-dev-api-key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"sk_live_xxxxxxxx"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-a&lt;/code&gt;&lt;/strong&gt; — account; often your macOS username or an app name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/strong&gt; — service string; this is the &lt;strong&gt;handle&lt;/strong&gt; you’ll use later. Make it unique, e.g. &lt;code&gt;myapp-dev-api-key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-w&lt;/code&gt;&lt;/strong&gt; — the secret. The problem is anything after &lt;code&gt;-w&lt;/code&gt; can land in &lt;strong&gt;shell history&lt;/strong&gt; (see below).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Read&lt;/strong&gt; it (prints to stdout):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;security find-generic-password &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"myapp-dev-api-key"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use it as an env var&lt;/strong&gt; for this shell only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MYAPP_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;security find-generic-password &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"myapp-dev-api-key"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, anything that reads &lt;code&gt;MYAPP_API_KEY&lt;/code&gt; behaves as if you’d sourced a &lt;code&gt;.env&lt;/code&gt;—except the value never had to live in a plaintext file on disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoiding shell history when you add the secret
&lt;/h2&gt;

&lt;p&gt;Apple’s own usage text says bluntly that &lt;strong&gt;&lt;code&gt;-p&lt;/code&gt; / &lt;code&gt;-w&lt;/code&gt; on the command line is insecure&lt;/strong&gt;. Two patterns that actually work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built-in prompt (often the nicest):&lt;/strong&gt; put &lt;strong&gt;&lt;code&gt;-w&lt;/code&gt; last and omit the value&lt;/strong&gt;. &lt;code&gt;security&lt;/code&gt; will prompt for the password; that path doesn’t shove the secret into your history the way &lt;code&gt;-w "secret"&lt;/code&gt; does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;security add-generic-password &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"myapp-dev-api-key"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(When it asks, type or paste the secret; it’s the usual “no echo” style prompt.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shell-side prompt&lt;/strong&gt; if you prefer to stay in bash/zsh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'Paste secret (hidden): '&lt;/span&gt;
&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-rs&lt;/span&gt; SECRET
&lt;span class="nb"&gt;echo
&lt;/span&gt;security add-generic-password &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"myapp-dev-api-key"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SECRET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;unset &lt;/span&gt;SECRET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Keychain Access&lt;/strong&gt; still counts: &lt;strong&gt;File → New Password Item…&lt;/strong&gt; and line up the fields with whatever you pass as &lt;code&gt;-a&lt;/code&gt; / &lt;code&gt;-s&lt;/code&gt; so &lt;code&gt;find-generic-password&lt;/code&gt; can find the item later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wiring it into how you actually work
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Every new terminal&lt;/strong&gt; (Zsh snippet in &lt;code&gt;~/.zshrc&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MYAPP_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;security find-generic-password &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"myapp-dev-api-key"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; just keeps noise down if the item doesn’t exist yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per project&lt;/strong&gt;, a small &lt;code&gt;scripts/load-secrets.sh&lt;/code&gt; that exports what that repo needs is reasonable—&lt;strong&gt;don’t commit values&lt;/strong&gt;; document the &lt;strong&gt;service names&lt;/strong&gt; in the README so someone else can add their own copy to Keychain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One shot:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MYAPP_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;security find-generic-password &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"myapp-dev-api-key"&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; uv run python &lt;span class="nt"&gt;-m&lt;/span&gt; myapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What you gain, what you’re signing up for
&lt;/h2&gt;

&lt;p&gt;You lose the plaintext secret sitting in &lt;code&gt;.env&lt;/code&gt; (and in a lot of accidental greps and backups). It’s &lt;strong&gt;built in&lt;/strong&gt;, no extra install, and Keychain can &lt;strong&gt;nudge or block&lt;/strong&gt; access per app if you tune &lt;strong&gt;Access Control&lt;/strong&gt; on the item. For “this laptop only” dev keys, that’s often plenty.&lt;/p&gt;

&lt;p&gt;The flip side is boring but real: &lt;strong&gt;Linux and Windows&lt;/strong&gt; won’t help you here—those teammates need 1Password CLI, Doppler, SOPS, cloud IAM, whatever your team standard is. There’s &lt;strong&gt;no automatic team sync&lt;/strong&gt;; new machine usually means re-adding items (iCloud Keychain exists but that’s a deliberate trust choice). If you &lt;strong&gt;echo&lt;/strong&gt; secrets or log them, you’ve undone the point. &lt;strong&gt;CI&lt;/strong&gt; wants provider-native secrets, not interactive Keychain. Onboarding is also slightly worse than “copy &lt;code&gt;.env.example&lt;/code&gt;”—people need the &lt;strong&gt;exact service strings&lt;/strong&gt; and commands written down somewhere.&lt;/p&gt;

&lt;p&gt;I still reach for this for &lt;strong&gt;solo Mac dev&lt;/strong&gt; and small personal projects where I want fewer sensitive files lying around. For &lt;strong&gt;shared, audited, rotated&lt;/strong&gt; secrets at work, use the thing your platform team points you at.&lt;/p&gt;




&lt;p&gt;So: you store with &lt;code&gt;security&lt;/code&gt;, load with &lt;code&gt;export&lt;/code&gt; and &lt;code&gt;$(security find-generic-password … -w)&lt;/code&gt;, and you get env-var ergonomics without a plaintext &lt;code&gt;.env&lt;/code&gt; for that value. The cost is &lt;strong&gt;macOS-only&lt;/strong&gt;, a bit more &lt;strong&gt;documentation&lt;/strong&gt;, and &lt;strong&gt;discipline&lt;/strong&gt; around history and logging.&lt;/p&gt;

</description>
      <category>macos</category>
      <category>security</category>
      <category>keychain</category>
      <category>bash</category>
    </item>
    <item>
      <title>Cost Optimizations in AWS - Part 1</title>
      <dc:creator>Ayomide Adebisi</dc:creator>
      <pubDate>Sun, 05 Jun 2022 14:14:33 +0000</pubDate>
      <link>https://forem.com/alsaheem/cost-optimizations-in-aws-part-1-25mn</link>
      <guid>https://forem.com/alsaheem/cost-optimizations-in-aws-part-1-25mn</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofu9uvk9gubyq9lkthe5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofu9uvk9gubyq9lkthe5.jpg" alt="Image description" width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm not really a fan of writing, but here i am still doing it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Here are some tips i believe would be helpful with cost optimization on AWS
&lt;/h2&gt;

&lt;p&gt;This are the steps i take to reduce my costs on aws cloud&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. EC2 Instance Type&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When choosing an instance type for a particular workload, here are some questions to ask yourself&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions to ask yourself ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the use case for this workload ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This question above helps you understand the need for the particular workload. This leads me to the questions below&lt;/p&gt;

&lt;p&gt;What is the capacity Ram ,Cpu or Storage? &lt;br&gt;
How often would the instance be utilized - would be instance be running a machine learning application. and needs more compute , would it just be running a light web application e.t.c ?&lt;/p&gt;

&lt;p&gt;These questions helps you select the best instance to select on the basis of memory , cpu or ram usage,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Elastic IP's&lt;/strong&gt;&lt;br&gt;
Elastic IP addresses can actually add cost to your infrastructure when not in use. since IPv4 addresses are limited , it makes sense that AWS charges you for them when not in use and makes it free when in use. also note that attaching 2 EIP addresses to the same instance would still require AWS to charge you. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. AWS Instance scheduler&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/solutions/implementations/instance-scheduler/" rel="noopener noreferrer"&gt;https://aws.amazon.com/solutions/implementations/instance-scheduler/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Development services and other non-production services (instance and database) can be turned off when not in use.&lt;/p&gt;

&lt;p&gt;This can be automated by using AWS Instance Scheduler which helps you automate the process of keeping your instances down based on your custom schedule (when you believe that no one is currently using the services). This can be done for a company running on a 9-5 basis that has a non-production instance and database running . The company can schedule the services by 5:30 pm daily and bring them back online by 8am the next morning. This would be fully automated by instance scheduler.&lt;/p&gt;

&lt;p&gt;Adding EC2 instances and Database instances to instance scheduler can be done by tagging the instances with the created instance scheduler name&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Autoscaling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;if the autoscaling is frequent on your service (i.e you scale like 1 - 5 times in the hour), you might need to change your instance size to a more stable instance. This can help you reduce your costs and reduce the scaling frequency of your application during peak limits. Also if you understand the timing and trend of traffic into your service, you should look at scheduled scaling to help scale the service at periods of high traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Spot instances&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spot instances can give a great reduction in cost because . Spot Instances are a cost-effective choice if you can be flexible about when your applications run and if your applications can be interrupted. For example, Spot Instances are well-suited for data analysis, batch jobs, background processing, and optional tasks. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use RDS serverless for non-production database instances with infrequent usage. RDS Serverless reduces the instances running the database when not being used, This dosen't mean that your database would not be running. This means that it would be in a sleep mode when no API calls have been made to the database for a while. when the database is in a sleep mode, the first call is usually a but slow before the database picks up the usual work pace. This is perfect for non-production environments. you only pay for  what you use.&lt;/p&gt;

&lt;p&gt;RDS Aurora : This is the best&lt;/p&gt;

&lt;h2&gt;
  
  
  Some AWS tools to give you more insights into your resources and services cost
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;AWS Trusted Advisor(based on past 30 days)
Tells you about the following&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Amazon reserved instance optimization&lt;br&gt;
Idle load balancers&lt;br&gt;
Underutilized EBS volumes&lt;br&gt;
Unassociated EIP addresses&lt;br&gt;
Idle RDS db instances&lt;br&gt;
Amazon Route53 latency resource record sets&lt;br&gt;
Underutilised Amazon Redshift Clusters&lt;/p&gt;




</description>
      <category>aws</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
