{"id":20593336,"url":"https://github.com/objectisadvantag/macros-env","last_synced_at":"2026-05-01T04:34:47.046Z","repository":{"id":89281379,"uuid":"235727877","full_name":"ObjectIsAdvantag/macros-env","owner":"ObjectIsAdvantag","description":"Environment variables for Webex Devices macros","archived":false,"fork":false,"pushed_at":"2023-06-06T12:04:49.000Z","size":435,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-17T00:17:17.787Z","etag":null,"topics":["env","node","serverless","webex-devices","xapi"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ObjectIsAdvantag.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-23T05:16:41.000Z","updated_at":"2023-06-06T12:07:37.000Z","dependencies_parsed_at":"2024-11-07T22:47:19.149Z","dependency_job_id":null,"html_url":"https://github.com/ObjectIsAdvantag/macros-env","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Fmacros-env","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Fmacros-env/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Fmacros-env/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Fmacros-env/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ObjectIsAdvantag","download_url":"https://codeload.github.com/ObjectIsAdvantag/macros-env/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242225530,"owners_count":20092592,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["env","node","serverless","webex-devices","xapi"],"created_at":"2024-11-16T07:48:05.142Z","updated_at":"2026-05-01T04:34:46.982Z","avatar_url":"https://github.com/ObjectIsAdvantag.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Environment variables for Macros [![published](https://static.production.devnetcloud.com/codeexchange/assets/images/devnet-published.svg)](https://developer.cisco.com/codeexchange/github/repo/ObjectIsAdvantag/macros-env)\n\nEnhance your Webex Devices Macro runtime with environment variables:\n- ENV is shared across macros on the same device\n- ENV can be volatile or persisted (by default)\n- ENV can be modified over HTTP on the LAN \n- if cloud-registered, a device ENV can be modified over Webex /xapi endpoint)\n\n\n## Usage\n\nWait for the 'env-ready' event and load variables for local ENV:\n\n\u003e note : there are multiple options when it comes to initializing a macro with ENV variables. Check the [example folder](examples/) for other coding styles and use cases.\n\n```javascript\nconst xapi = require('xapi');\n\n// Wait for ENV variables to be accesible\nxapi.on('env-ready', async (ready) =\u003e {\n\n   const value = await getenv('DEVICE_SECRET');\n\n   xapi.command('UserInterface Message Prompt Display', {\n      Title: 'ENV',\n      Text: `$DEVICE_SECRET = ${value}`,\n      Duration: 10\n   });\n   \n});\n\n//\n// ENV library\n//   - getenv() function\n//\n...\n```\n\n\n## Quickstart\n\n1. Deploy the [environment](environment.js) macro to a device.\n\n2. Activate the 'environment' macro.\n\n3. Copy the [env-ready](env-ready.min.js) macro to the device, and activate it too.\n\n   \u003e You can pick either the minified or expanded version of 'env-ready'.\n\n4. Check the logs in the Macro Editor, you should see:\n\n   ```text\n   08:22:00\t[system]    Using XAPI transport: TSH\n   08:22:00\t[system]    Starting macros...\n   08:22:00\tenvironment Loading...\n   08:22:00\tgetenv      Loading...\n   08:22:02\tgetenv      Ready!\n   08:22:02\tenvironment Ready!\n   08:22:02\tenvironment'starting in persistent mode: environment variables are stored in the \"ENV\" macro.'\n   08:22:03\tgetenv     'echo $DEVICE_SECRET = 1234'\n   ```\n\n\n5. Congrats, your ENV is working!\n\n   You can now copy the [env-ready](env-ready.min.js) code snippet to an existing macro,\n   and initialize your macro from the `xapi.on('env-ready', async (ready) =\u003e { ... })` code block.\n   Check the [examples folder](examples/) for inspiration.\n\n   _Note that if a variable is not found in ENV, an empty value is returned._\n\n\n## To go further\n\n- **Customize the DEFAULT_ENV** with a predefined the list of ENV variables for your macros in [environment](environment.js):\n\n   ```javascript\n   const DEFAULT_ENV = {\n      'DEVICE_SECRET': 2345,\n      'WEBEX_TOKEN': \"ABCDEFGHIJ\"\n   }\n   ```\n\n\n- **Configure your ENV to be volatile or persistent** by changing the value of volatile in in [environment](environment.js): \n\n   The environment is volatile by default.\n\n   ```javascript\n   const volatile = true; // set to false for persisted ENV variables\n   ```\n   \n   When changed to persistent, a 'ENV' file will be automatically created with the contents of the DEFAULT_ENV. \n   The 'ENV' file is materialized by another macro on your device. \n   Refresh the Macro Editor to make the 'ENV' macro appear. \n   \n   As you update the DEFAULT_ENV in the 'environment' macro, make sure to delete the 'ENV' macro in order to re-initialize the ENV of the device.\n\n\n- **Create or update ENV variables** by sending a message on the LAN or from the cloud\n\n   \u003e Note: the commands below won't work if the communications via Message/Send/Text commands are encrypted (see below)\n\n   ```shell\n   # on the LAN: place your credentials\n   curl --request POST '{{endpoint}}/putxml' \\\n        --header 'Content-Type: text/xml' \\\n        --header 'Authorization: Basic {{credentials}}' \\\n        --data-raw '\u003cCommand\u003e\n            \u003cMessage\u003e\n               \u003cSend\u003e\n                  \u003cText\u003e{'\\''env'\\'': '\\''DEVICE_SECRET'\\'', '\\''operation'\\'': '\\''set'\\'', '\\''value'\\'': 9876 }\u003c/Text\u003e\n               \u003c/Send\u003e\n            \u003c/Message\u003e\n         \u003c/Command\u003e'\n   ```\n\n\n   ```shell\n   # over the Cloud\n   #  - replace the token with a Webex bot or admin token with the 'spark:xapi_commands' scope\n   #  - paste the Webex identifier of your devices (from the Webex /devices API)\n   curl --request POST 'https://api.ciscospark.com/v1/xapi/command/message.send' \\\n      --header 'Authorization: Bearer WEBEX_ACCESS_TOKEN' \\\n      --header 'Content-Type: application/json' \\\n      --data-raw '{\n         \"deviceId\": \"Y2lzY29FyazovL3VzL0RFVklDRS83MzYLTQ3OGEtOTMyNC0xZmZiNjNmMjQzNWU\",\n         \"arguments\": {\n            \"Text\": \"{'\\''env'\\'': '\\''DEVICE_SECRET'\\'', '\\''operation'\\'': '\\''set'\\'', '\\''value'\\'': 789}\"\n         }\n      }'\n   ```\n\n- **Troubleshooting**\n\n   Open the 'environment' macro, and change the value of `TRACE_MESSAGES` to `true` to trace the communications between the 'environment' and other macros.\n\n\n## Architecture\n\n### Background information\n\nWhen deploying CE customizations, one (or several combined) of the strategies below must be used to deal with secrets:\n- inject secrets along the CI/CD pipeline [see diagram](img/deploy_cicd.png)\n- dynamically load secrets from a Vault [see diagram](img/load_vault.png)\n- or load secrets from the local device, which is the purpose of this project (see below)\n\n\n### Architecture\n\nUsing a Pub/Sub pattern, macros can request environment variables from an 'Environment' macro, that can provide static , volative or persisted values.\n\n![macro_env](img/macro_env.png)\n\n\n### Design\n\nThis project uses the device local bus to enable communication across Macros.\n\n![local_bus](img/local_bus.png)\n\n\nMoreover, the code uses several pattenrs to implement features not supported by CE:\n- ordering of Macros (to ensure the 'Environment' macros is accessible before others macros are run)\n- data persistance (to persist environment variables across macro runtime restarts)\n\n\n## Security concerns\n\nThe communications between the macros reading the ENV, and the 'environment' macro managing the ENV are send in clear text, via xCommand 'Message Send Text'.\n\nAs 'Message Send' events can be listened by code with an 'Integrator' role, this represents a potential vulnerability if secrets were to be stored in the env.\n\nWe recommend to enhance the security of your deployment by using one or both of: encrypted communications and encryption at rest.\n\n### Encrypted communications\n\nThe 'environment' macro and 'getenv()' function support encrypted communications.\n\nTurn on the encrypted boolean both the 'environment' macro and 'getenv()' function to start seeing the message flying as encrypted.\n\nA 'secret-based' and symetric encryption implementation is provided in the proposed implementation.\nFeel free to replace / enhance with a crypto algorithm that better meets your needs.\n\n\n### Encryption at rest\n\nIf secrets are to be stored, we recommend you encrypt these secrets before passing them to the environment.\n\nCheck the xapi-samples for examples of [symetric](https://github.com/CiscoDevNet/xapi-samples/blob/master/macros/15-cipher.js) and [asymetric](https://github.com/CiscoDevNet/xapi-samples/blob/master/macros/16-encrypt-rsa.js) algorithms compatible with CE's macro runtime.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjectisadvantag%2Fmacros-env","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobjectisadvantag%2Fmacros-env","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjectisadvantag%2Fmacros-env/lists"}