# Good way to make sure my gateway scripts only run on the server?

**URL:** <https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777>\
**Category:** Ignition\
**Tags:** ignition80\
**Created:** [April 8, 2020, 12:48pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777 "2020-04-08T12:48:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [April 8, 2020, 12:48pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/1 "2020-04-08T12:48:44Z")

</div>

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 essential to the functioning of the application. What would be the best/most modular way to make it so I/my coworkers can export a copy of my production gateway to a development VM or my own localhost, and not have to worry about accidentally running gateway scripts?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 8, 2020, 12:56pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/2 "2020-04-08T12:56:05Z")

</div>

Consider placing a JSON encoded file in your production gateway’s filesystem containing configuration values for environment-dependent items. Place an alternate version in each development server. Load it in the top level of a project script at the root of your inheritance tree, so that it can be accessed trivially where needed, something like `myGlobalScript.myConfigJson.someItem`. Anything that should only run in Production, or do something specific differently, would check that JSON object for the decision.

The chosen filesystem location must be _ **outside** _ any source-control scope.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [April 8, 2020, 1:20pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/3 "2020-04-08T13:20:33Z")

</div>

Ok I think this is sort of what I saw in a Flask tutorial, so I think I understand what you’re saying, correct me if I’m wrong. I’d have a script in a module myConfigJson

```auto
def runOnGateway():
    """
    Determines if a script should run on the gateway.
    """
    import OS
   try:
       # Some code here to grab the json object from the file
       return json[someItem]
   except OSError:
       # For when the file does not exist
       return False

```

Then in my gateway scripts

```auto
import myConfigJson

if myConfigJson.runOnGateway():
    # rest of my script here

```

Where my json file would be something like

```auto
config = {
    runOnGateway = True,
}

```

I did see some other project someone did using IP’s but I really dislike hardcoding IP addresses into code. I like your idea of a config file.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 8, 2020, 1:23pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/4 "2020-04-08T13:23:00Z")

</div>

You could also rely on environment variables that you access via [`System.getenv()`](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getenv--). It’s the same idea as the JSON config file and the same way many web applications are deployed - certain configuration details are pulled from the environment rather than from code or configuration files that are part of the application.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [April 8, 2020, 1:31pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/5 "2020-04-08T13:31:51Z")

</div>

Ah ok, how would I get access to this through scripting? Also, I see there’s no setEnv - how would I set the environment variable? I can’t tell from the documentation. Also, how would I actually use this via scripting?

```auto
import system
system.getEnv()

```

does not work.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 8, 2020, 1:36pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/6 "2020-04-08T13:36:12Z")

</div>

Something like this:

```auto
import java.lang.System

prod = System.getenv().get("IGNITION_PROD")

```

These environment variables are read-only, you wouldn’t set them from Ignition, which is kind of the point.

edit: looks like `System.getenv("IGNITION_PROD")` also works.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [April 8, 2020, 1:48pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/7 "2020-04-08T13:48:04Z")

</div>

Ok I got that to work, howver running

```auto
import java.lang.System as System

prod = System.getenv().get("IGNITION_PROD")

print str(prod)

```

on both my development designer and my production designer consoles, prod is None in both instances. I do see there are other options in getenv() I can probably use though, but what is “IGNITION\_PROD” supposed to represent? It seems odd its None on my unlicensed development designer and my licensed/activated production designer.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 8, 2020, 1:53pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/8 "2020-04-08T13:53:38Z")

</div>

I’d probably not bother with the function. Just access the json object directly. The custom module would have something like this:

```auto
import json

with open("/path/to/my/json/file.json", "r") as f:
    myConfigJson = json.load(f)

```

Then in your other scripts, all you’d do is:

```auto
if myGlobalScript.myConfigJson['runOnGateway']:
    # do something on production gateway
else:
    # fake it on a dev gateway

```

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 8, 2020, 1:55pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/9 "2020-04-08T13:55:50Z")

</div>

That’s an environment variable name that I made up for the purpose of this example. It could be whatever you want it to be. You have to set it in your actual production environment if you want it to be available (which, again, is the point).

> **[Environment variable](https://en.wikipedia.org/wiki/Environment_variable)**
>
> An environment variable is a dynamic-named value that can affect the way running processes will behave on a computer. They are part of the environment in which a process runs. For example, a running process can query the value of the TEMP environment variable to discover a suitable location to store temporary files, or the HOME or USERPROFILE variable to find the directory structure owned by the user running the process.
> They were introduced in their modern form in 1979 with Version 7 Unix, so...

> **[How To Set Environment Variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html)**
>
> Learn why environment variables are useful and how to set them on Windows, macOS, Linux and other systems.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 8, 2020, 2:03pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/10 "2020-04-08T14:03:59Z")

</div>

If you are going the environment variable route, you might find python’s `os.environ` dictionary to be most convenient.  
In module:

```auto
import os

runOnGateway = bool(os.environ['SOME_ENV_VARIABLE'])

```

In other scripts:

```auto
if myGlobalScript.runOnGateway:
    # do something on production gateway
else:
    # fake it on a dev gateway

```

Note that environment variables are really bad places to put anything private. If you need different credentials for production versus dev, use the JSON file approach.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 8, 2020, 2:08pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/11 "2020-04-08T14:08:19Z")

</div>

> [@pturmel](#):
>
> Note that environment variables are really bad places to put anything private.

Putting secrets in environment variables is a generally accepted practice because usually your application is running on a server where users can't arbitrarily run scripts or read from the env.

But... Ignition is not such an application. Anybody with designer access can read the env variables. And fwiw, anybody with designer access can read your JSON file too, so it's only marginally more secure via obscurity.

(anybody with designer access should be trusted)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 8, 2020, 2:18pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/12 "2020-04-08T14:18:17Z")

</div>

> [@Kevin.Herron](#):
>
> Putting secrets in environment variables is a generally accepted practice

Uh, no. Heck, no. A sample of contrary opinions:

> **[Why you shouldn't use ENV variables for secret data](https://blog.diogomonica.com//2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/)**
>
> If your application requires a password, SSH private key, TLS Certificate, or any other kind of sensitive data, you shouldn't pass it alongside your configs.

Even when Microsoft is recommending storing secrets in environment variables instead of in an app's code itself, they have a big fat warning, and then describe how to use their JSON infrastructure instead:

> **[Safe storage of app secrets in development in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1)**
>
> Learn how to store and retrieve sensitive information during the development of an ASP.NET Core app.

So, no, just no. No secrets in the environment.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 8, 2020, 2:19pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/13 "2020-04-08T14:19:57Z")

</div>

> [@Kevin.Herron](#):
>
> (anybody with designer access should be trusted)

This, yes. Any designer, in the hands of a malicious user, can take total control of a gateway in spite of role-based security.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [April 8, 2020, 2:21pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/14 "2020-04-08T14:21:53Z")

</div>

I am trying to get better at understanding the security aspect of Ignition so someone please correct me if im wrong -

To summarize, if someone has designer access, they’d easily be able to see my environment variables with the system.getEnv() script right? But unless they had access to the server itself they could not change that.

Where as the config.json method, they would have to search my scripts to find it. But if they could find it, would they be able to edit it via designer? Couldn’t they open it up, read it, edit it, and resave it with a script?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 8, 2020, 2:29pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/15 "2020-04-08T14:29:22Z")

</div>

If they crack Ignition itself, or otherwise gain access as the Ignition service user, yes. They’d be able to read that file. As another user, no, you can set the security on the file to prevent other users access. Similar to what is done to protect SSL private keys.  
If they gain root access, all bets are off. Labeling files for SELinux can help even that case, though.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [April 8, 2020, 2:31pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/16 "2020-04-08T14:31:13Z")

</div>

Ah ok that was the piece missing in my head, you would have set security on the file to not allow other users to edit. Thanks

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 8, 2020, 2:37pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/17 "2020-04-08T14:37:06Z")

</div>

You could prevent even Ignition from writing back to the JSON file by letting root own it, and set its group to something that only Ignition belongs to, and let the group have read-only access.

As for manipulating environment variables, at least in java memory, you might enjoy all the hacks in this StackOverflow post:

> <https://stackoverflow.com/questions/318239/how-do-i-set-environment-variables-from-java>

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [May 27, 2020, 4:21pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/18 "2020-05-27T16:21:02Z")

</div>

Hey, just wanted to give an update, it seems while running the script to get environment variables on a designer running on the gateway works, trying to run the

```auto
import java.lang.System as System

prod = System.getenv().get("IGNITION_PROD")

print str(prod)

```

on a gateway script always gives me a None even though there is an environment variable.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 27, 2020, 4:46pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/19 "2020-05-27T16:46:57Z")

</div>

Where are you setting this environment variable? In modern Linux, systemd units are started with sanitized environments. You have to define additional variables there. In windows, services will see only system environment variable, IIRC.

{Not that I’m suggesting this… I still think @Kevin.Herron is wrong… (: }

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [May 27, 2020, 5:46pm UTC](https://forum.inductiveautomation.com/t/good-way-to-make-sure-my-gateway-scripts-only-run-on-the-server/33777/20 "2020-05-27T17:46:39Z")

</div>

I take it back. I accidentally added to the variables for Administrator at the top  
instead of System Variables at the bottom. Works fine now. Was just developer induced error.  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/2X/a/a42155158b180a9c4e517b692ac9c1f5eb0eba1e.png)
