# Best practice for an API key

**URL:** <https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088>\
**Category:** Maker\
**Created:** [June 26, 2020, 2:00pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088 "2020-06-26T14:00:13Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mcarritt1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mcarritt1/32/4262_2.png) [@mcarritt1](https://forum.inductiveautomation.com/u/mcarritt1)\
**Post date:** [June 26, 2020, 2:00pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088/1 "2020-06-26T14:00:13Z")

</div>

I was going to start in on making something using an existing API. Anyone have any thoughts about the best way to store API keys or passwords? In the past I’ve use base64 to encode them and put them in the sql database but thats just one step above storing them as basic text.

---

<div class="post-metadata">

**Author:** ![KGarner](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgarner/32/15999_2.png) [@KGarner](https://forum.inductiveautomation.com/u/KGarner)\
**Post date:** [June 26, 2020, 2:32pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088/2 "2020-06-26T14:32:29Z")

</div>

I don’t know about “best practices” per se, but I tend to store them as environment variables on the OS

---

<div class="post-metadata">

**Author:** ![mcarritt1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mcarritt1/32/4262_2.png) [@mcarritt1](https://forum.inductiveautomation.com/u/mcarritt1)\
**Post date:** [June 26, 2020, 3:03pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088/3 "2020-06-26T15:03:41Z")

</div>

I’m not familiar with this, would it persist after a restart?

---

<div class="post-metadata">

**Author:** ![KGarner](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgarner/32/15999_2.png) [@KGarner](https://forum.inductiveautomation.com/u/KGarner)\
**Post date:** [June 26, 2020, 3:31pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088/4 "2020-06-26T15:31:49Z")

</div>

Yep, it’s a pretty solid way in my experience. You can see how to set an environment variable [here](https://www.schrodinger.com/kb/1842).

Python also has a pretty simple way of getting an environment variable:

```auto
import os
print(os.environ['HOME'])

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 26, 2020, 4:34pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088/5 "2020-06-26T16:34:38Z")

</div>

Some previous discussion around this in this thread:

> [@Good way to make sure my gateway scripts only run on the server?](http://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777):
>
> More of a design question than anything. I have gateway scripts, some of which involve emailing our companies clients. On occasion, I’ve had coworkers unknowingly backup the gateway to a development machine with an old database copy, and then all of a sudden our clients are getting emails with outdated information that they already received. Not great. Currently I’ve been telling people to not export/import gateway scripts, but there are other scripts that don’t involve emails that are essen…

In general, the most important thing is to limit the scope of where you secret can possibly be read from. There's some filesystem based suggestions in that thread that are good practice. Environment variables _can_ work, but aren't guaranteed to be as isolated as you might like them to be, as @pturmel points out in that thread.

Ideally, anything interacting with an API would eventually become an Ignition module - in that case, you can store them encrypted & salted in the internal DB, which is a nice bonus.

---

<div class="post-metadata">

**Author:** ![mcarritt1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mcarritt1/32/4262_2.png) [@mcarritt1](https://forum.inductiveautomation.com/u/mcarritt1)\
**Post date:** [June 26, 2020, 4:40pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088/6 "2020-06-26T16:40:26Z")

</div>

hrm ok thanks for the input. maybe I just won’t worry too much about it for now until its time to make it a module

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 26, 2020, 4:58pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-an-api-key/36088/7 "2020-06-26T16:58:16Z")

</div>

If anyone’s interested in learning a bit about Java development, you can refine this proof of concept I just whipped up:

> **[paul-griffith/secret-keeper](https://github.com/paul-griffith/secret-keeper)**
>
> Toy, incomplete Ignition proof-of-concept module to store secrets in the IDB - paul-griffith/secret-keeper

It adds a new section to the config page of the gateway that lets you define named secret values, and then (within the gateway scope) you can run `system.secrets.getSecret(<name>)` to retrieve the un-encoded value.
