Skip to content

Instantly share code, notes, and snippets.

@t1m0thyj
Last active March 9, 2021 20:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t1m0thyj/c142c668a4353844d469901cf7ce3634 to your computer and use it in GitHub Desktop.
Save t1m0thyj/c142c668a4353844d469901cf7ce3634 to your computer and use it in GitHub Desktop.

Options for storing secure values in team config

Table of contents

Current approach

zowe.config.json file on disk

{
  "profiles": {
    "my_zosmf": {
      "type": "zosmf",
      "properties": {
        "host": "example.com"
      }
    }
  },
  "secure": [
    "profiles.my_zosmf.properties.user",
    "profiles.my_zosmf.properties.password"
  ]
}

Zowe/secure_config_props object in Credential Manager

{
  "C:\\dev\\zowe.config.json": {
    "profiles.my_zosmf.properties.user": "<redacted>",
    "profiles.my_zosmf.properties.password": "<redacted>"
  },
}

Disadvantages of current approach

  1. Secure properties are not visible alongside plain text properties. It may be difficult for users to understand how/where the secure properties are being used.
  2. It is necessary to use long JSON paths to list the properties in the secure array. These may be difficult for users to construct and understand.
  3. Secure credentials are stored in association with a config file path. Renaming/moving a config JSON file means its secure values are forgotten and must be re-entered. (This is a separate issue tracked in #967.)

Alternative approaches that have been suggested

  1. Define secure properties using objects

    {
      "profiles": {
        "my_zosmf": {
          "type": "zosmf",
          "properties": {
            "host": "example.com",
            "user": { "secure": "my_user" },
            "password": { "secure": "my_password" }
          }
        }
      }
    }

    Pros: This addresses all of the disadvantages mentioned above:

    1. ✔️ Secure properties are moved inside the properties object alongside plain text properties.
    2. ✔️ The user doesn't need to understand any long JSON paths, and can update credentials with a simple command (e.g., zowe config set --secure my_user)
    3. ✔️ Secure credentials are stored under unique IDs "my_user" and "my_password". They are not associated with a specific config JSON file, so other config files can use the same IDs "my_user" or "my_password" and share the same secure value.

    Cons:

    • This is a breaking change. Profile properties are currently allowed to store complex objects such as { "secure": "XXX" }. If Zowe CLI interprets some objects in a special way, it is no longer safe to store JSON objects in a property without stringifying them.
    • Zowe CLI won't know when credentials are no longer used and can be deleted [1]. With the current approach, credentials are safe to delete if they're associated with config JSON files that no longer exist.
    • This will be a significant change to implement, as well as to roll out to existing @next users, since it changes the way credentials are stored in the vault.
  2. Define secure properties with string constant

    {
      "profiles": {
        "my_zosmf": {
          "type": "zosmf",
          "properties": {
            "host": "example.com",
            "user": "managed by Secure Credential Manager",
            "password": "managed by Secure Credential Manager"
          }
        }
      }
    }

    Pros: This addresses some of the disadvantages mentioned above:

    1. ✔️ Secure properties are moved inside the properties object alongside plain text properties.
    2. ❌ The user still needs to provide long JSON paths for the "config set" command (e.g., zowe config set --secure profiles.my_zosmf.properties.user)
    3. ❌ Secure credentials are still associated with config file paths, and will be forgotten when config JSON files are renamed/moved.

    Cons: Items marked with ❌ in the list above + the cons listed for approach #1

  3. Store secure properties in array inside of profile

    {
      "profiles": {
        "my_zosmf": {
          "type": "zosmf",
          "properties": {
            "host": "example.com"
          },
          "secure": [
            "user",
            "password"
          ]
        }
      }
    }

    Pros: This addresses some of the disadvantages mentioned above:

    1. ✔️ Secure properties are moved near the properties object alongside plain text properties.
    2. ❌ The user still needs to provide long JSON paths for the "config set" command, although they could be abbreviated to "short JSON paths" like the ones used in the defaults object (e.g., zowe config set --secure my_zosmf.user)
    3. ❌ Secure credentials are still associated with config file paths, and will be forgotten when config JSON files are renamed/moved.

    Cons: Items marked with ❌ in the list above

Bonus alternative approach

To address #967, there is yet another alternative approach that can handle file renames/moves.

This approach does not move the location of the "secure" property in config JSON files. Because of this, it could be combined with any of the approaches above that include disadvantage #3:

Secure credentials are still associated with config file paths, and will be forgotten when config JSON files are renamed/moved.

  1. Associate secure properties with GUIDs instead of file paths

    {
      "secureId": "<guid>",
      "profiles": {
        ...
      }
    }

    Pros:

    • If each config JSON file contains a GUID, that would provide a unique ID to identify the file which stays the same even when the file is renamed/moved.

    Cons:

    • Zowe CLI won't know when credentials are no longer used and can be deleted [1]. With the current approach, credentials are safe to delete if they're associated with config JSON files that no longer exist.
    • This will be a significant change to implement, as well as to roll out to existing @next users, since it changes the way credentials are stored in the vault.

Evaluation of alternative approaches

Each of the alternatives have pros and cons that allow us to "weight" them compared to the current approach:

  1. +3/-3 = 0
  2. +1/-5 = -4
  3. +1/-2 = -1
  4. +1/-2 = -1

When evaluated this way, none of these alternative approaches are significantly better.

Endnotes

  1. This is important on Windows, where it is ideal to keep the length of credentials stored in OS Credential Manager as small as possible. If all secure fields combined exceed 2560 bytes, they must be split and stored across multiple locations in the vault and thus take longer to load.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment