mirror of
https://github.com/LukeHagar/jims-blog.git
synced 2025-12-07 20:47:49 +00:00
25 lines
14 KiB
HTML
25 lines
14 KiB
HTML
<!doctype html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=x-ua-compatible content="ie=edge"><link rel=icon href=/fav.png type=image/png><link rel=preconnect href=https://fonts.googleapis.com><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=preload as=style href="https://fonts.googleapis.com/css2?family=Alata&family=Lora&family=Muli:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Roboto&family=Muli:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"><link rel=stylesheet href="https://fonts.googleapis.com/css2?family=Alata&family=Lora&family=Muli:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Roboto&family=Muli:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" media=print onload='this.media="all"'><noscript><link href="https://fonts.googleapis.com/css2?family=Alata&family=Lora&family=Muli:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Roboto&family=Muli:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet></noscript><link rel=stylesheet href=/css/font.css media=all><meta property="og:title" content="Hiding API keys from Git"><meta property="og:description" content="I’ve been working on a Xamarin app using Azure Cognitive Services to do image recognition, and one of the stumbling blocks I’ve faced is what to do with my API keys. I want to make the app open source as an example of how to use these services, but don’t want to check my API keys into Git to be available to all - after all, bad things can happen."><meta property="og:type" content="article"><meta property="og:url" content="https://jimbobbennett.dev/blogs/hiding-api-keys-from-git/"><meta property="og:image" content="https://jimbobbennett.dev/blogs/hiding-api-keys-from-git/banner.png"><meta property="article:section" content="blogs"><meta property="article:published_time" content="2017-12-28T19:35:50+00:00"><meta property="article:modified_time" content="2017-12-28T19:35:50+00:00"><meta property="og:site_name" content="JimBobBennett"><meta name=twitter:card content="summary_large_image"><meta name=twitter:image content="https://jimbobbennett.dev/blogs/hiding-api-keys-from-git/banner.png"><meta name=twitter:title content="Hiding API keys from Git"><meta name=twitter:description content="I’ve been working on a Xamarin app using Azure Cognitive Services to do image recognition, and one of the stumbling blocks I’ve faced is what to do with my API keys. I want to make the app open source as an example of how to use these services, but don’t want to check my API keys into Git to be available to all - after all, bad things can happen."><meta name=twitter:site content="@jimbobbennett"><meta name=twitter:creator content="@jimbobbennett"><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css integrity=sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3 crossorigin=anonymous><link rel=stylesheet href=/css/header.css media=all><link rel=stylesheet href=/css/footer.css media=all><link rel=stylesheet href=/css/theme.css media=all><link rel="shortcut icon" type=image/png href=/fav.png><link rel="shortcut icon" sizes=192x192 href=/fav.png><link rel=apple-touch-icon href=/fav.png><link rel=alternate type=application/rss+xml href=https://jimbobbennett.dev/index.xml title=JimBobBennett><script type=text/javascript>(function(e,t,n,s,o,i,a){e[n]=e[n]||function(){(e[n].q=e[n].q||[]).push(arguments)},i=t.createElement(s),i.async=1,i.src="https://www.clarity.ms/tag/"+o,a=t.getElementsByTagName(s)[0],a.parentNode.insertBefore(i,a)})(window,document,"clarity","script","dctc2ydykv")</script><style>:root{--text-color:#343a40;--text-secondary-color:#6c757d;--background-color:#000;--secondary-background-color:#64ffda1a;--primary-color:#007bff;--secondary-color:#f8f9fa;--text-color-dark:#e4e6eb;--text-secondary-color-dark:#b0b3b8;--background-color-dark:#000000;--secondary-background-color-dark:#212529;--primary-color-dark:#ffffff;--secondary-color-dark:#212529}body{background-color:#000;font-size:1rem;font-weight:400;line-height:1.5;text-align:left}</style><meta name=description content><link rel=stylesheet href=/css/index.css><link rel=stylesheet href=/css/single.css><link rel=stylesheet href=/css/projects.css media=all><script defer src=/fontawesome-5/all-5.15.4.js></script><title>Hiding API keys from Git | JimBobBennett</title></head><body class=light onload=loading()><header><nav class="pt-3 navbar navbar-expand-lg"><div class="container-fluid mx-xs-2 mx-sm-5 mx-md-5 mx-lg-5"><a class="navbar-brand primary-font text-wrap" href=/><img src=/fav.png width=30 height=30 class="d-inline-block align-top">
|
|
JimBobBennett</a>
|
|
<button class=navbar-toggler type=button data-bs-toggle=collapse data-bs-target=#navbarContent aria-controls=navbarContent aria-expanded=false aria-label="Toggle navigation"><svg aria-hidden="true" height="24" viewBox="0 0 16 16" width="24" data-view-component="true"><path fill-rule="evenodd" d="M1 2.75A.75.75.0 011.75 2h12.5a.75.75.0 110 1.5H1.75A.75.75.0 011 2.75zm0 5A.75.75.0 011.75 7h12.5a.75.75.0 110 1.5H1.75A.75.75.0 011 7.75zM1.75 12a.75.75.0 100 1.5h12.5a.75.75.0 100-1.5H1.75z"/></svg></button><div class="collapse navbar-collapse text-wrap primary-font" id=navbarContent><ul class="navbar-nav ms-auto text-center"><li class="nav-item navbar-text"><a class=nav-link href=/ aria-label=home>Home</a></li><li class="nav-item navbar-text"><a class=nav-link href=/#about aria-label=about>About</a></li><li class="nav-item navbar-text"><a class=nav-link href=/#projects aria-label=projects>Recent Highlights</a></li><li class="nav-item navbar-text"><a class=nav-link href=/blogs title="Blog posts">Blog</a></li><li class="nav-item navbar-text"><a class=nav-link href=/videos title=Videos>Videos</a></li><li class="nav-item navbar-text"><a class=nav-link href=/livestreams title=Livestreams>Livestreams</a></li><li class="nav-item navbar-text"><a class=nav-link href=/conferences title=Conferences>Conferences</a></li><li class="nav-item navbar-text"><a class=nav-link href=/resume title=Resume>Resume</a></li></ul></div></div></nav></header><div id=content><section id=projects><div class="container pt-5" id=list-page><div class="row justify-content-center px-3 px-md-5"><h1 class="text-left pb-2 content">Hiding API keys from Git</h1><div class="text-left content">Jim Bennett
|
|
<small>|</small>
|
|
Dec 28, 2017</div></div></div></section><section id=single><div class=container><div class="row justify-content-center"><div class="col-sm-12 col-md-12 col-lg-9"><div class=pr-lg-4><article class="page-content p-2"><p>I’ve been working on a <a href=/blogs/identifying-my-daughters-toys-using-ai/>Xamarin app using Azure Cognitive Services to do image recognition</a>, and one of the stumbling blocks I’ve faced is what to do with my API keys. I want to make the app open source as an example of how to use these services, but don’t want to check my API keys into Git to be available to all - after all, <a href=https://www.theregister.co.uk/2015/01/06/dev_blunder_shows_github_crawling_with_keyslurping_bots/>bad things can happen</a>.</p><p>I hit up twitter, and got a really awesome solution from <a href=https://twitter.com/bartlannoeye>Bart Lannoeye</a>:</p><blockquote class=twitter-tweet data-conversation=none data-lang=en><p lang=en dir=ltr>You can add the file with *your key here* then change locally and git update-index --assume-unchanged .\pathtofile. Shows file as unchanged => can't commit by accident. <a href="https://twitter.com/hashtag/protip?src=hash&ref_src=twsrc%5Etfw">#protip</a> We do the same for Kliva.</p>— Bart Lannoeye (@bartlannoeye) <a href="https://twitter.com/bartlannoeye/status/946437185372413952?ref_src=twsrc%5Etfw">December 28, 2017</a></blockquote><script async src=https://platform.twitter.com/widgets.js></script><p>This is exactly what I did, and it works perfectly. I’ve created a static class called <code>ApiKeys</code> which contains all my keys using “Your Key Here” values:</p><pre tabindex=0><code>public static class ApiKeys
|
|
{
|
|
public static string PredictionKey = "<Your API Key>";
|
|
public static Guid ProjectId = Guid.Parse("<Your Project GUID>");
|
|
}
|
|
</code></pre><p>I then added this to Git and commited. After my commit I ran:</p><pre tabindex=0><code>git update-index --assume-unchanged ./ApiKeys.cs
|
|
</code></pre><p>Done. I can then change the values to my actual API keys and Git doesn’t see the change.</p><p>Obviously if I need to add any more keys to this file I’d have to revert this change, remove all keys, add the new one with a “your key” type value, commit, re-run the update-index and put the keys back. A bit of work, but at least no worries about anyone abusing my API limits!</p><p>Thanks Bart!</p><hr><p><strong>Update - how to tell users what they need to do with this code</strong></p><p>I’ve just had another great suggestion from <a href=https://developer.microsoft.com/en-gb/advocates/brandon-minnick>Brandon Minnick</a>, a fellow CDA here at Microsoft. He suggests adding a <code>#error</code> to the keys file so that when someone grabs the code and builds it they get an error telling them what to do, rather than a crash when the app is run:</p><pre tabindex=0><code>public static class ApiKeys
|
|
{
|
|
# error You need to set up your API keys.
|
|
// Start by registering for an account at https://customvision.ai
|
|
// Then create a new project.
|
|
// From the settings tab, find:
|
|
// Prediction Key
|
|
// Project Id
|
|
// and update the values below
|
|
public static string PredictionKey = "<Your Prediction Key>";
|
|
public static Guid ProjectId = Guid.Parse("<Your Project GUID>");
|
|
}
|
|
</code></pre><hr><p><strong>Update 2 - how to fix it if you forget and add your keys</strong></p><p>Another great tip from <a href=https://developer.microsoft.com/en-gb/advocates/brandon-minnick>Brandon Minnick</a> is the <a href=https://rtyley.github.io/bfg-repo-cleaner/>BFG Repo-CLeaner</a>. If you accidentally checked in some API keys, this tool can remove them from the Git history.</p><p>Obviously it could be too late by the time you realize, so if you check any API keys in to a public repo you <strong>MUST</strong> regenerate them as there are <a href=http://www.timbroder.com/2015/01/my-2375-amazon-ec2-mistake.html>bots that can GitHub for API keys</a>. But this is good for a private repo that you are planning to make public or accidentally add personal keys to.</p></article></div></div><div class="col-sm-12 col-md-12 col-lg-3"><div class=sticky-sidebar><aside class=toc><h5>Table Of Contents</h5><div class=toc-content><nav id=TableOfContents></nav></div></aside><aside class=tags><h5>Tags</h5><ul class="tags-ul list-unstyled list-inline"><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/azure target=_blank>azure</a></li><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/technology target=_blank>technology</a></li><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/api target=_blank>api</a></li><li class=list-inline-item><a href=https://jimbobbennett.dev/tags/keys target=_blank>keys</a></li></ul></aside></div></div></div><div class=row><div class="col-sm-12 col-md-12 col-lg-9 p-4"><div id=disqus_thread></div><script>var disqus_config=function(){this.page.url="https://jimbobbennett.dev/blogs/hiding-api-keys-from-git/",this.page.identifier="78d5d516394c6df579caaec81a98d8a0"};(function(){if(window.location.hostname=="localhost")return;var e=document,t=e.createElement("script");t.src="https://jimbobbennett.disqus.com/embed.js",t.setAttribute("data-timestamp",+new Date),(e.head||e.body).appendChild(t)})()</script><noscript>Please enable JavaScript to view the <a href=https://disqus.com/?ref_noscript>comments powered by Disqus.</a></noscript></div></div></div><button class="p-2 px-3" onclick=topFunction() id=topScroll>
|
|
<i class="fas fa-angle-up"></i></button></section><script>var topScroll=document.getElementById("topScroll");window.onscroll=function(){scrollFunction()};function scrollFunction(){document.body.scrollTop>20||document.documentElement.scrollTop>20?topScroll.style.display="block":topScroll.style.display="none"}function topFunction(){document.body.scrollTop=0,document.documentElement.scrollTop=0}</script></div><footer><div class="container py-4"><div class="row justify-content-center"><div class="col-md-4 text-center">© 2023 All Rights Reserved</div></div></div></div></footer><script src=https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js integrity=sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13 crossorigin=anonymous></script>
|
|
<script>document.body.className.includes("light")&&(document.body.classList.add("dark"),localStorage.setItem("pref-theme","dark"))</script><script>let loadingIcons;function loading(){myVar=setTimeout(showPage,100)}function showPage(){try{document.getElementById("loading-icons").style.display="block"}catch{}}</script><script>function createCopyButton(e,t){const n=document.createElement("button");n.className="copy-code-button",n.type="button",n.innerText="Copy",n.addEventListener("click",()=>copyCodeToClipboard(n,e,t)),addCopyButtonToDom(n,e)}async function copyCodeToClipboard(e,t,n){const s=t.querySelector("pre > code").innerText;try{n.writeText(s)}finally{codeWasCopied(e)}}function codeWasCopied(e){e.blur(),e.innerText="Copied!",setTimeout(function(){e.innerText="Copy"},2e3)}function addCopyButtonToDom(e,t){t.insertBefore(e,t.firstChild);const n=document.createElement("div");n.className="highlight-wrapper",t.parentNode.insertBefore(n,t),n.appendChild(t)}if(navigator&&navigator.clipboard)document.querySelectorAll(".highlight").forEach(e=>createCopyButton(e,navigator.clipboard));else{var script=document.createElement("script");script.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard-polyfill/2.7.0/clipboard-polyfill.promise.js",script.integrity="sha256-waClS2re9NUbXRsryKoof+F9qc1gjjIhc2eT7ZbIv94=",script.crossOrigin="anonymous",script.onload=function(){addCopyButtons(clipboard)},document.querySelectorAll(".highlight").forEach(e=>createCopyButton(e,script)),document.body.appendChild(script)}</script></body></html> |