Skip to content

Server Groups

The Server Groups resource provides access to all methods relating to Server Groups management in Keystash. Server Groups are logical groups of servers to allow for quick and easy bulk management of User privileges and SSH service policy.

List Server Groups

Path: /server-groups/list

Method: GET

Authentication: Bearer Token

Request Headers

Key Value Required
Accept-Encoding gzip optional

Request Parameters

All parameters are optional. Combine as many as you need and they are all applied together.

Key Data Type Required Notes
ids array of string optional One or more Server Group id values, 1–16 alphanumeric characters each. Note the plural: the resource here is the Server Group.
name string optional 1–255 characters. Matches any group whose name contains this value.
description string optional 1–255 characters. Matches any group whose description contains this value.
default_group boolean optional true, false, 1 or 0. Returns the default Server Group, or everything but it.
connection_logging boolean optional true, false, 1 or 0. Filters on whether SSH Connection Logging is enabled for the group.
password_auth_enabled boolean optional true, false, 1 or 0.
two_factor_enabled boolean optional true, false, 1 or 0.
two_factor_disallow_reuse boolean optional true, false, 1 or 0.
two_factor_allow_unenrolled boolean optional true, false, 1 or 0.
start_date string optional Inclusive lower bound on the group's created date, in UTC YYYY-MM-DD HH:mm:ss. Must be supplied with end_date and must not be later than it.
end_date string optional Inclusive upper bound on the group's created date, in UTC YYYY-MM-DD HH:mm:ss. Must be supplied with start_date.
limit integer optional Rows to return. Defaults to 250, which is also the maximum; a larger value is reduced to 250.
offset integer optional Row offset for paging. Defaults to 0.

Note

A parameter that is not recognised, or a value that fails its rule, returns a 400 BadArgument naming every parameter at fault. See Filtering Lists for the full rules, and Paging Through Lists for the X-Total-Count, X-Limit and X-Offset headers.

Tip

To find your default Server Group, filter on ?default_group=true rather than reading the first row of the list. Server Groups are returned in name order.

Request Body

None.

Example Request

curl --location --request GET 'https://app.keystash.io/api/v1/server-groups/list' \
--header 'Authorization: Bearer <token>'

Narrowing the list to the groups that enforce Two Factor Authentication:

curl --location --request GET 'https://app.keystash.io/api/v1/server-groups/list?two_factor_enabled=true&limit=50' \
--header 'Authorization: Bearer <token>'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Total-Count: 2
X-Limit: 250
X-Offset: 0

[
  {
    "id": "Gfz5m9mGuIp6ByPz",
    "name": "Production Servers",
    "description": "All production servers.",
    "version": 117,
    "default_group": true,
    "connection_logging": true,
    "password_auth_enabled": true,
    "two_factor_enabled": false,
    "two_factor_disallow_reuse": true,
    "two_factor_window_size": 1,
    "two_factor_rate_limit": 3,
    "two_factor_allow_unenrolled": false,
    "created": "2022-04-03 16:03:42",
    "created_user_id": "x0Uf09z8TYjoNVFB",
    "created_by": "Max Smith",
    "modified": "2023-09-25 07:28:22",
    "modified_user_id": "x0Uf09z8TYjoNVFB",
    "modified_by": "Max Smith"
  },
  {
    "id": "rzbSZtL2zI0oA16V",
    "name": "Production Databases",
    "description": "",
    "version": 85,
    "default_group": false,
    "connection_logging": false,
    "password_auth_enabled": false,
    "two_factor_enabled": true,
    "two_factor_disallow_reuse": true,
    "two_factor_window_size": 2,
    "two_factor_rate_limit": 3,
    "two_factor_allow_unenrolled": true,
    "created": "2022-05-25 12:22:41",
    "created_user_id": "x0Uf09z8TYjoNVFB",
    "created_by": "Max Smith",
    "modified": "2023-09-25 07:28:22",
    "modified_user_id": "x0Uf09z8TYjoNVFB",
    "modified_by": "Max Smith"
  }
]

Example Error Response

Invalid Filter Value (400 Bad Request)

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "One or more query parameters were invalid.",
    "details": [
      {
        "field": "two_factor_enabled",
        "message": "Expected a boolean value.",
        "received": "banana",
        "allowed_values": ["true", "false", "1", "0"]
      }
    ]
  }
}

No Server Groups (404 Not Found)

A 404 here means your company has no Server Groups at all. A filter that matches nothing returns a 200 OK with an empty array ([]), as does an offset past the end of the results.

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "Your request was successfully processed but there was no data to be returned.",
    "details": []
  }
}

View Server Group

Path: /server-groups/view

Method: GET

Authentication: Bearer Token

Request Headers

Key Value Required
Accept-Encoding gzip optional

Request Parameters

Key Data Type Required Notes
id string required The ID of the server group to view

Request Body

None.

Example Request

curl --location --request GET 'https://app.keystash.io/api/v1/server-groups/view?id=BD720EP87kNORRcH' \
--header 'Authorization: Bearer <token>'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "id": "BD720EP87kNORRcH",
  "name": "Production Databases",
  "description": "",
  "version": 633,
  "default_group": true,
  "connection_logging": true,
  "password_auth_enabled": false,
  "two_factor_enabled": true,
  "two_factor_disallow_reuse": true,
  "two_factor_window_size": 1,
  "two_factor_rate_limit": 3,
  "two_factor_allow_unenrolled": false,
  "created": "2021-01-09 19:10:47",
  "created_user_id": "bkQV8I5BRcAVpgod",
  "created_by": "Max Smith",
  "modified": "2024-05-21 14:19:47",
  "modified_user_id": "bkQV8I5BRcAVpgod",
  "modified_by": "Max Smith"
}

Example Error Response

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "Your request was successfully processed but there was no data to be returned.",
    "details": []
  }
}

Create Server Group

Path: /server-groups/create

Method: POST

Authentication: Bearer Token

Request Headers

Key Value Required
Content-Type application/json required

Request Parameters

None.

Request Body Parameters

Key Data Type Required Notes
name string required The name of the server group
description string optional Description of the server group
connection_logging boolean optional Whether SSH Connection Logging is enabled for servers in this group. When enabled, the Keystash Agent records SSH session authentication events, which are surfaced in the SSH Sessions resource and the app's SSH Sessions view. Requires a Keystash Agent version that supports SSH session logging. Defaults to true if not provided.
password_auth_enabled boolean required Whether password authentication is enabled. Note: Cannot be set to true if two_factor_enabled is true.
two_factor_enabled boolean required Whether two-factor authentication is enabled. Note: Cannot be set to true if password_auth_enabled is true.
two_factor_disallow_reuse boolean required Whether to allow Two Factor codes to be used more than once. This option determines if you are able to use a Two Factor 6 Digit pin more than once in a 30 second window. For example: If you open two SSH connections to the same server in short succession you would be prompted for a Two Factor Authentication 6 digit pin. If you entered in the pin on the first SSH session you would have to wait for a new 6 digit pin to generate before you could login on the second connection. Disabling this option allows you to use the same 6 digit pin two or more times in quick succession. We suggest enabling this for increased security.
two_factor_allow_unenrolled boolean required Whether users who have not yet enrolled in Two Factor Authentication are permitted to log in to servers in this group. This setting only takes effect when two_factor_enabled is true. We suggest leaving this disabled so that every user must complete Two Factor Authentication enrolment before they can log in.
two_factor_window_size integer optional Allowance for time difference between server and your mobile phone - As Keystash uses the TOTP algorithm it is important to ensure that all servers using SSH Two Factor Authentication have a reliable NTP source. This is so that all your users mobile phones and all the servers have the correct date and time. Large differences (over 2 minutes) can cause issues during SSH Two Factor Authentication. To help combat these issues you can allow for medium (75 seconds) and large (130 seconds) differences between the servers clocks and the mobile phones clocks. Normal is considered the most secure but is the most strict. The available options for this setting are: 1 = Normal, 2 = Medium and 3 = Large. Defaults to 1 (Normal) if not provided.
two_factor_rate_limit integer optional The rate limit for two-factor authentication attempts. Available options are: 1,2,3 or 4. 1 = (Off) No rate limiting. 2 = (Permissive) 10 logins every 30 seconds per user account. 3 = (Normal) 3 logins every 30 seconds per user account. 4 = (Restrictive) 1 login every 30 seconds per user account. Defaults to 3 (Normal) if not provided.

Note

SSH Connection Logging feeds the SSH Sessions resource. To learn more about the feature and how sessions are recorded, see the user-facing Server Groups and SSH Sessions pages.

Example Request Body

{
    "name": "My Group",
    "description": "My Group of servers",
    "connection_logging": true,
    "password_auth_enabled": false,
    "two_factor_enabled": true,
    "two_factor_disallow_reuse": true,
    "two_factor_allow_unenrolled": false,
    "two_factor_window_size": 3,
    "two_factor_rate_limit": 2
}

Example Request

curl --location --request POST 'https://app.keystash.io/api/v1/server-groups/create' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data-raw '{
    "name": "My Group",
    "description": "My Group of servers",
    "connection_logging": true,
    "password_auth_enabled": false,
    "two_factor_enabled": true,
    "two_factor_disallow_reuse": true,
    "two_factor_allow_unenrolled": false,
    "two_factor_window_size": 3,
    "two_factor_rate_limit": 2
}'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "result": "Server Group was successfully created.",
    "id": "BD720EP87kNORRcH"
}

Example Error Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
    "error": {
        "code": "BadArgument",
        "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
        "details": [
            {
                "field": "name",
                "message": "name is a required field and cannot be empty."
            }
        ]
    }
}

Set Default Server Group

Path: /server-groups/set-default

Method: POST

Authentication: Bearer Token

Request Headers

Key Value Required
Content-Type application/json required

Request Parameters

None.

Request Body Parameters

Key Data Type Required Notes
id string required The ID of the server group to set as default

Example Request Body

{
    "id": "BD720EP87kNORRcH"
}

Example Request

curl --location --request POST 'https://app.keystash.io/api/v1/server-groups/set-default' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data-raw '{
    "id": "BD720EP87kNORRcH"
}'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "result": "Server Group with ID BD720EP87kNORRcH was successfully updated."
}

Example Error Response

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "Your request was successfully processed but there was no data to be returned.",
    "details": []
  }
}

Update Server Group

Path: /server-groups/update

Method: PATCH

Authentication: Bearer Token

Request Headers

Key Value Required
Content-Type application/json required

Request Parameters

None.

Request Body Parameters

Key Data Type Required Notes
id string required The ID of the server group to update
name string optional The name of the server group
description string optional Description of the server group
connection_logging boolean optional Whether SSH Connection Logging is enabled for servers in this group. When enabled, the Keystash Agent records SSH session authentication events, which are surfaced in the SSH Sessions resource and the app's SSH Sessions view. Requires a Keystash Agent version that supports SSH session logging. If not provided, the current value is left unchanged.
password_auth_enabled boolean optional Whether password authentication is enabled. Note: Cannot be set to true if two_factor_enabled is true.
two_factor_enabled boolean optional Whether two-factor authentication is enabled. Note: Cannot be set to true if password_auth_enabled is true.
two_factor_disallow_reuse boolean optional Whether to allow Two Factor codes to be used more than once. This option determines if you are able to use a Two Factor 6 Digit pin more than once in a 30 second window. For example: If you open two SSH connections to the same server in short succession you would be prompted for a Two Factor Authentication 6 digit pin. If you entered in the pin on the first SSH session you would have to wait for a new 6 digit pin to generate before you could login on the second connection. Disabling this option allows you to use the same 6 digit pin two or more times in quick succession. We suggest enabling this for increased security.
two_factor_allow_unenrolled boolean optional Whether users who have not yet enrolled in Two Factor Authentication are permitted to log in to servers in this group. This setting only takes effect when two_factor_enabled is true. We suggest leaving this disabled so that every user must complete Two Factor Authentication enrolment before they can log in. If not provided, the current value is left unchanged.
two_factor_window_size integer optional Allowance for time difference between server and your mobile phone - As Keystash uses the TOTP algorithm it is important to ensure that all servers using SSH Two Factor Authentication have a reliable NTP source. This is so that all your users mobile phones and all the servers have the correct date and time. Large differences (over 2 minutes) can cause issues during SSH Two Factor Authentication. To help combat these issues you can allow for medium (75 seconds) and large (130 seconds) differences between the servers clocks and the mobile phones clocks. Normal is considered the most secure but is the most strict. The available options for this setting are: 1 = Normal, 2 = Medium and 3 = Large. Defaults to 1 (Normal) if not provided.
two_factor_rate_limit integer optional The rate limit for two-factor authentication attempts. Available options are: 1,2,3 or 4. 1 = (Off) No rate limiting. 2 = (Permissive) 10 logins every 30 seconds per user account. 3 = (Normal) 3 logins every 30 seconds per user account. 4 = (Restrictive) 1 login every 30 seconds per user account. Defaults to 3 (Normal) if not provided.

Example Request Body

{
    "id": "BD720EP87kNORRcH",
    "name": "API Test Group",
    "description": "New description.",
    "connection_logging": true,
    "two_factor_window_size": 1,
    "two_factor_rate_limit": 1
}

Example Request

curl --location --request PATCH 'https://app.keystash.io/api/v1/server-groups/update' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data-raw '{
    "id": "BD720EP87kNORRcH",
    "name": "API Test Group",
    "description": "New description.",
    "connection_logging": true,
    "two_factor_window_size": 1,
    "two_factor_rate_limit": 1
}'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "result": "Server Group with ID BD720EP87kNORRcH was successfully updated."
}

Example Error Response

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "Your request was successfully processed but there was no data to be returned.",
    "details": []
  }
}

Delete Server Group

Path: /server-groups/delete

Method: DELETE

Authentication: Bearer Token

Request Headers

Key Value Required
Accept-Encoding gzip optional

Request Parameters

Key Data Type Required Notes
id string required The ID of the server group to delete

Request Body

None.

Example Request

curl --location --request DELETE 'https://app.keystash.io/api/v1/server-groups/delete?id=BD720EP87kNORRcH' \
--header 'Authorization: Bearer <token>'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "result": "Server Group with ID BD720EP87kNORRcH was successfully deleted."
}

Example Error Response

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "Your request was successfully processed but there was no data to be returned.",
    "details": []
  }
}

List Users in Server Group

This endpoint returns every user in your company, each carrying the permission level they hold on the named Server Group. A user with no access to the group appears with a permission_level of Disabled rather than being left out, so the list is a permissions view of the group rather than a membership list.

Note

Because the response covers every user in your company, a company with more than 250 users spans several pages. To check one particular user, narrow the request with ?user_ids[]=<id> rather than searching through the pages.

Path: /server-groups/list-users

Method: GET

Authentication: Bearer Token

Request Headers

Key Value Required
Accept-Encoding gzip optional

Request Parameters

Every parameter other than id is optional. Combine as many as you need and they are all applied together.

Key Data Type Required Notes
id string required The id of the Server Group whose users are listed. 1–16 alphanumeric characters. A missing or malformed value returns a 400 BadArgument, and a well-formed but unknown value returns a 404 NotFound.
user_ids array of string optional One or more user id values, being the user_id field in a response. Each is 1–16 alphanumeric characters.
firstname string optional 1–255 characters. Matches any user whose first name contains this value.
lastname string optional 1–255 characters. Matches any user whose last name contains this value.
email string optional 1–255 characters. Matches any user whose email contains this value.
server_username string optional 1–255 characters. Matches any user whose Server Username contains this value.
permission_level array of string optional One or more of Disabled, User, Root. Case-insensitive. Matches the effective permission level shown in the response, after User Group inheritance has been resolved.
override_groups boolean optional true, false, 1 or 0. Filters on whether the user's settings override those inherited from their User Groups.
permission_level_inherited boolean optional true, false, 1 or 0. Filters on whether the permission level shown is inherited from a User Group.
linux_groups_inherited boolean optional true, false, 1 or 0. Filters on whether the Linux Groups shown are inherited from a User Group.
limit integer optional Rows to return. Defaults to 250, which is also the maximum; a larger value is reduced to 250.
offset integer optional Row offset for paging. Defaults to 0.

Note

permission_level filters on the level the user effectively has, which is the level in the response. A user who is Root through a User Group matches ?permission_level[]=Root even though the permission was never assigned to them directly. You can read more about how this is resolved here.

Note

A parameter that is not recognised, or a value that fails its rule, returns a 400 BadArgument naming every parameter at fault. See Filtering Lists for the full rules, and Paging Through Lists for the X-Total-Count, X-Limit and X-Offset headers.

Request Body

None.

Example Request

curl --location --request GET 'https://app.keystash.io/api/v1/server-groups/list-users?id=BD720EP87kNORRcH' \
--header 'Authorization: Bearer <token>'

Narrowing the list to the users who hold root access on the group, 100 rows at a time:

curl --location --request GET 'https://app.keystash.io/api/v1/server-groups/list-users?id=BD720EP87kNORRcH&permission_level[]=Root&limit=100' \
--header 'Authorization: Bearer <token>'

Response Fields

A successful response is a JSON array of user objects, returned in last name, then first name order.

Field Data Type Description
user_id string The unique ID of the user
firstname string The user's first name
lastname string The user's last name
server_username string The username used on servers for this user
email string The user's email address
permission_level string The effective permission level for this user in the server group. Possible values: "Root", "User", "Disabled"
override_groups boolean Indicates whether the user has individual permission settings that override inherited settings from User Groups
permission_level_inherited boolean Indicates whether the user's permission level is inherited from User Groups. When true and override_groups is false, the permission level comes from User Group membership
linux_groups_inherited boolean Indicates whether the user's Linux groups are inherited from User Groups. When true and override_groups is false, the Linux groups come from User Group membership
linux_groups array Array of Linux group objects assigned to the user. Each object contains id (the Linux group's ID) and name (the Linux group's name)

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Total-Count: 3
X-Limit: 250
X-Offset: 0

[
  {
    "user_id": "bkQV8I5BRcAVpgod",
    "firstname": "Max",
    "lastname": "Smith",
    "server_username": "maxsmith",
    "email": "max.smith@example.org",
    "permission_level": "Root",
    "override_groups": false,
    "permission_level_inherited": false,
    "linux_groups_inherited": false,
    "linux_groups": [
      {
        "id": "Gfz5m9mGuIp6ByPz",
        "name": "developers"
      },
      {
        "id": "rzbSZtL2zI0oA16V",
        "name": "admins"
      }
    ]
  },
  {
    "user_id": "t2er3Mo68eFWMbVk",
    "firstname": "Anne",
    "lastname": "Teak",
    "server_username": "anneteak",
    "email": "anne.teak@example.org",
    "permission_level": "User",
    "override_groups": false,
    "permission_level_inherited": true,
    "linux_groups_inherited": true,
    "linux_groups": [
      {
        "id": "Gfz5m9mGuIp6ByPz",
        "name": "developers"
      }
    ]
  },
  {
    "user_id": "ZaPkEfpPIlhKv3eO",
    "firstname": "Perry",
    "lastname": "Scope",
    "server_username": "perryscope",
    "email": "perry.scope@example.org",
    "permission_level": "Disabled",
    "override_groups": true,
    "permission_level_inherited": false,
    "linux_groups_inherited": false,
    "linux_groups": []
  }
]

Example Error Response

Missing or Malformed ID (400 Bad Request)

The id of the Server Group is required, so a request without it is rejected before anything is read. A value that is present but is not a 1–16 character alphanumeric id is reported the same way, with a received field echoing the value you sent.

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "One or more query parameters were invalid.",
    "details": [
      {
        "field": "id",
        "message": "Required. The id of the Server Group whose users are being listed."
      }
    ]
  }
}

Server Group Not Found (404 Not Found)

A 404 here means the Server Group id is unknown or belongs to another company. A Server Group that has nothing to list returns a 200 OK with an empty array ([]), as does an offset past the end of the results.

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "Your request was successfully processed but there was no data to be returned.",
    "details": []
  }
}

Update User in Server Group

Path: /server-groups/update-user

Method: PATCH

Authentication: Bearer Token

Request Headers

Key Value Required
Content-Type application/json required

Request Parameters

None

Request Body Parameters

Key Data Type Required Notes
server_group_id string required The ID of the server group
user_id string required The ID of the user to update
permission_level string required The new permission level for the user. Options are "Disabled", "User" and "Root".
override_groups boolean optional Whether to override inherited settings from User Groups. When true, the user's individual permission and Linux group settings take precedence over those inherited from User Groups. When false or not provided, settings are inherited from User Groups. Defaults to false.
linux_group_ids array optional Array of Linux group IDs to assign to the user in this server group. Each element should be a string containing a valid Linux group ID. If not provided, existing Linux group assignments remain unchanged.
linux_groups array optional Array of Linux group objects with IDs to assign to the user in this server group. Each element should be an object containing a valid Linux group ID. If not provided, existing Linux group assignments remain unchanged.
Note You should only provide linux_group_ids OR linux_groups, never both. The system will always prioritise and use linux_group_ids over linux_groups. linux_groups is provided as a convenience field allowing users to copy linux_groups from the response provided by /server-groups/list-user-groups API endpoint.

Example Request Body

{
    "server_group_id": "BD720EP87kNORRcH",
    "user_id": "bkQV8I5BRcAVpgod",
    "permission_level": "User",
    "override_groups": true,
    "linux_group_ids": ["Gfz5m9mGuIp6ByPz", "rzbSZtL2zI0oA16V"],
    "linux_groups": [{"id": "Gfz5m9mGuIp6ByPz"}, {"id": "rzbSZtL2zI0oA16V"}]
}

Example Request

curl --location --request PATCH 'https://app.keystash.io/api/v1/server-groups/update-user' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data-raw '{
    "server_group_id": "BD720EP87kNORRcH",
    "user_id": "bkQV8I5BRcAVpgod",
    "permission_level": "User",
    "override_groups": true,
    "linux_group_ids": ["Gfz5m9mGuIp6ByPz", "rzbSZtL2zI0oA16V"]
}'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "result": "Server Group with ID BD720EP87kNORRcH was successfully updated."
}

Example Error Response

Missing Required Parameters (400 Bad Request)

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "The following required parameters are missing from your request: server_group_id, user_id"
    ]
  }
}

Invalid Permission Level (400 Bad Request)

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "Invalid permission level provided. Valid options are: Root, User, Disabled"
    ]
  }
}

User Not Found (404 Not Found)

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "Could not find a User for the User ID provided."
    ]
  }
}

Server Group Not Found (404 Not Found)

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "Could not find a Server Group for the Server Group ID provided."
    ]
  }
}

Linux Groups Not Found (404 Not Found)

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "Could not find Linux Groups with IDs: xyz123abc456"
    ]
  }
}

Database Save Error (500 Internal Server Error)

HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "DataSaveError",
    "message": "There was a system problem while saving data to the database.",
    "details": []
  }
}

List User Groups in Server Group

This endpoint returns the User Groups that hold something on the named Server Group, being a permission, a Linux Group, or both. A User Group with neither is not listed. To see every User Group in your company, use List User Groups and match the results yourself.

Path: /server-groups/list-user-groups

Method: GET

Authentication: Bearer Token

Request Headers

Key Value Required
Accept-Encoding gzip optional

Request Parameters

Every parameter other than id is optional. Combine as many as you need and they are all applied together.

Key Data Type Required Notes
id string required The id of the Server Group whose User Groups are listed. 1–16 alphanumeric characters. A missing or malformed value returns a 400 BadArgument, and a well-formed but unknown value returns a 404 NotFound.
user_group_ids array of string optional One or more User Group id values, being the user_group_id field in a response. Each is 1–16 alphanumeric characters.
name string optional 1–255 characters. Matches any User Group whose name contains this value.
description string optional 1–255 characters. Matches any User Group whose description contains this value.
permission_level array of string optional One or more of Unset, Disabled, User, Root. Case-insensitive. Unset matches a User Group that appears in this list on the strength of a Linux Group assignment alone, holding no permission level on the group.
limit integer optional Rows to return. Defaults to 250, which is also the maximum; a larger value is reduced to 250.
offset integer optional Row offset for paging. Defaults to 0.

Note

id names the Server Group you are listing against, and is required. user_group_ids filters the User Groups that come back. Sending ids here returns a 400 BadArgument.

Note

A parameter that is not recognised, or a value that fails its rule, returns a 400 BadArgument naming every parameter at fault. See Filtering Lists for the full rules, and Paging Through Lists for the X-Total-Count, X-Limit and X-Offset headers.

Request Body

None.

Example Request

curl --location --request GET 'https://app.keystash.io/api/v1/server-groups/list-user-groups?id=BD720EP87kNORRcH' \
--header 'Authorization: Bearer <token>'

Narrowing the list to the User Groups that grant access to the group:

curl --location --request GET 'https://app.keystash.io/api/v1/server-groups/list-user-groups?id=BD720EP87kNORRcH&permission_level[]=Root&permission_level[]=User' \
--header 'Authorization: Bearer <token>'

Response Fields

A successful response is a JSON array of User Group objects, returned in name order.

Field Data Type Description
user_group_id string The unique ID of the user group
name string The user group's name
description string The user group's description
permission_level string The permission level this User Group holds on the Server Group. One of Root, User, Disabled, or Unset when the User Group appears here on the strength of a Linux Group assignment alone
user_count integer The number of users in the user group
linux_groups array Array of Linux group objects assigned to the user group in this server group. Each object contains id (the Linux group's ID) and name (the Linux group's name)

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Total-Count: 3
X-Limit: 250
X-Offset: 0

[
  {
    "user_group_id": "p3Km8NxLtYqR9wZd",
    "name": "Development Team",
    "description": "Development team user group",
    "permission_level": "Root",
    "user_count": 5,
    "linux_groups": [
      {
        "id": "Gfz5m9mGuIp6ByPz",
        "name": "developers"
      },
      {
        "id": "rzbSZtL2zI0oA16V",
        "name": "admins"
      }
    ]
  },
  {
    "user_group_id": "v7QxRm2NhPzF4jLk",
    "name": "Operations Team",
    "description": "Operations and infrastructure team",
    "permission_level": "User",
    "user_count": 3,
    "linux_groups": [
      {
        "id": "Gfz5m9mGuIp6ByPz",
        "name": "developers"
      }
    ]
  },
  {
    "user_group_id": "n9TwYp5MkBvD8xRh",
    "name": "Contractors",
    "description": "",
    "permission_level": "Disabled",
    "user_count": 2,
    "linux_groups": []
  }
]

Example Error Response

Missing or Malformed ID (400 Bad Request)

The id of the Server Group is required, so a request without it is rejected before anything is read. A value that is present but is not a 1–16 character alphanumeric id is reported the same way, with a received field echoing the value you sent.

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "One or more query parameters were invalid.",
    "details": [
      {
        "field": "id",
        "message": "Required. The id of the Server Group whose User Groups are being listed."
      }
    ]
  }
}

Server Group Not Found (404 Not Found)

A 404 here means the Server Group id is unknown or belongs to another company. A Server Group with no User Groups holding a permission or a Linux Group on it returns a 200 OK with an empty array ([]), as does an offset past the end of the results.

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "Your request was successfully processed but there was no data to be returned.",
    "details": []
  }
}

Update User Group in Server Group

Path: /server-groups/update-user-group

Method: PATCH

Authentication: Bearer Token

Request Headers

Key Value Required
Content-Type application/json required

Request Parameters

None

Request Body Parameters

Key Data Type Required Notes
server_group_id string required The ID of the server group
user_group_id string required The ID of the user group to update
permission_level string required The permission level for the user group. Options are "Disabled", "User", "Root", or "Unset". Setting to "Unset" removes the user group's permissions from the server group. Note: Cannot set to "Unset" if the user group does not currently have permissions for this server group.
linux_group_ids array optional Array of Linux group IDs to assign to the user group in this server group. Each element should be a string containing a valid Linux group ID. If not provided, existing Linux group assignments remain unchanged.
linux_groups array optional Array of Linux group objects with IDs to assign to the user group in this server group. Each element should be an object containing a valid Linux group ID. If not provided, existing Linux group assignments remain unchanged.
Note You should only provide linux_group_ids OR linux_groups, never both. The system will always prioritise and use linux_group_ids over linux_groups. linux_groups is provided as a convenience field allowing users to copy linux_groups from the response provided by /server-groups/list-users API endpoint.

Example Request Body

{
    "server_group_id": "BD720EP87kNORRcH",
    "user_group_id": "p3Km8NxLtYqR9wZd",
    "permission_level": "Root",
    "linux_group_ids": ["Gfz5m9mGuIp6ByPz", "rzbSZtL2zI0oA16V"]
}

Example Request

curl --location --request PATCH 'https://app.keystash.io/api/v1/server-groups/update-user-group' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data-raw '{
    "server_group_id": "BD720EP87kNORRcH",
    "user_group_id": "p3Km8NxLtYqR9wZd",
    "permission_level": "Root",
    "linux_group_ids": ["Gfz5m9mGuIp6ByPz", "rzbSZtL2zI0oA16V"]
}'

Example Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "result": "Server Group with ID BD720EP87kNORRcH was successfully updated."
}

Example Error Response

Missing Required Parameters (400 Bad Request)

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "The following required parameters are missing from your request: server_group_id, user_group_id"
    ]
  }
}

Invalid Permission Level (400 Bad Request)

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      {
        "field": "permission_level",
        "validation": "value",
        "message": "The permission_level must be a string set to 'Disabled', 'User', 'Root' or 'Unset'."
      }
    ]
  }
}

Cannot Unset Non-Existent Permission (400 Bad Request)

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "BadArgument",
    "message": "Cannot unset a permission that does not exist. The User Group does not currently have any permissions for this Server Group.",
    "details": []
  }
}

User Group Not Found (404 Not Found)

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "Could not find a User Group for the User Group ID provided."
    ]
  }
}

Server Group Not Found (404 Not Found)

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "Could not find a Server Group for the Server Group ID provided."
    ]
  }
}

Linux Groups Not Found (404 Not Found)

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "NotFound",
    "message": "There was a problem with one or more arguments in your request. Please check your request and resubmit.",
    "details": [
      "Could not find Linux Groups with IDs: xyz123abc456"
    ]
  }
}

Database Save Error (500 Internal Server Error)

HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "DataSaveError",
    "message": "There was a system problem while saving data to the database.",
    "details": []
  }
}