Links

User & Role Management

Panther API user and role management operations

Overview

The Panther API supports the following user and role operations:
  • List users
  • Get a user by ID or by email address
  • Invite new users
  • Update a user's information and role
  • Delete users
  • List roles
  • Get a role by ID or by name
  • Create a new role
  • Update a role's information and permissions
  • Delete roles
You can invoke Panther's API by using your Console's API Playground, or the GraphQL-over-HTTP API. Learn more about these methods on Panther API.
See the sections below for GraphQL queries, mutations, and end-to-end workflow examples around core user and role management operations.

Common user and role management operations

Below are some of the most common GraphQL user and role management operations in Panther. These examples demonstrate the documents you have to send using a GraphQL client (or curl) to make a call to Panther's GraphQL API.
Note: The createdAt field is in ISO 8601 date and time standard.

Listing Users

query users {
users {
id
givenName
familyName
email
status
createdAt
lastLoggedInAt
role {
name
id
permissions
}
}
}

Retrieving a User

User by Email Address
User by ID
query user {
userByEmail(email: "[email protected]") {
id
givenName
familyName
email
role {
name
id
permissions
}
status
createdAt
}
}
query user {
userById(id: "8h81hfh-ij828db") {
id
givenName
familyName
email
role {
name
id
permissions
}
status
createdAt
}
}

Inviting a new User

mutation inviteUser {
inviteUser(input: {
givenName: "firstname"
familyName: "lastname"
role: {
kind: NAME
value: "Analyst"
}
})
{
user {
id
status
}
}
}

Updating a User

mutation updateUser {
updateUser(input: {
id: "8h81hfh-ij828db"
familyName: "newName"
})
{
user {
email
givenName
familyName
}
}
}

Deleting a User

mutation deleteUser{
deleteUser(input: {
id: "8h81hfh-ij828db"
})
{
id # the delete operation doesn't return a `user` object; just an ID
}
}

Listing Roles

query roles {
roles(
# This input is optional. Without input, the query will return all roles.
input: {
nameContains: "admin",
sortDir: ascending
})
{
createdAt
id
name
permissions
updatedAt
updatedBy {
... on User {
email
id
}
... on APIToken {
id
name
}
}
# Used only if RBAC per log type is enabled
logTypeAccess
logTypeAccessKind
}
}

Retrieving a Role

Role by Name
Role by ID
query adminRole {
roleByName(
name: "admin"
) {
createdAt
id
name
permissions
updatedAt
updatedBy {
... on User {
email
id
}
... on APIToken {
id
name
}
}
# Used only if RBAC per log type is enabled
logTypeAccess
logTypeAccessKind
}
}
query adminRole {
roleById(
id: "feeafade-c545"
) {
createdAt
id
logTypeAccess
logTypeAccessKind
name
permissions
updatedAt
updatedBy {
... on User {
email
id
}
... on APIToken {
id
name
}
}
# Used only if RBAC per log type is enabled
logTypeAccess
logTypeAccessKind
}
}

Creating a new Role

Note: The permission UserModify provides full admin access to the Panther platform. Use discretion when assigning this permission to new roles.
Basic
RBAC per log type enabled
mutation createRole {
createRole(input: {
name: "new-role"
permissions: [
UserRead
AlertRead
]
})
{
role {
name
id
permissions
}
}
}
mutation createRole {
createRole(input: {
name: "new-role"
permissions: [
UserRead
AlertRead
]
# Used only if the RBAC per log type feature is enabled
logTypeAccess:["AWS.ALB"]
logTypeAccessKind: ALLOW
})
{
role {
name
id
permissions
logTypeAccess
logTypeAccessKind
}
}
}

Updating a Role

Note: The permissions in the updateRole input must contain all desired permissions for the role.
Basic
RBAC per log type enabled
mutation updateRole {
updateRole(input: {
id: "fea8sje-92jdnhc"
name: "updated-role-name"
permissions: [
UserRead
AlertRead
AlertModify
]
})
{
role {
name
id
permissions
}
}
}
mutation updateRole {
updateRole(input: {
id: "fea8sje-92jdnhc"
name: "updated-role-name"
permissions: [
UserRead
AlertRead
AlertModify
]
# Used only if the RBAC per log type feature is enabled
logTypeAccess:["AWS.ALB"]
logTypeAccessKind: DENY
})
{
role {
name
id
permissions
logTypeAccess
logTypeAccessKind
}
}
}

Deleting a Role

mutation deleteRole {
deleteRole(input: {
id: "e146c8d8-c6a5"
})
{
id # The delete operation doesn't return a `role` object. Just an ID.
}
}

End-to-end examples

Below, we will build on the Common Operations examples to showcase an end-to-end flow.

Create a new user administrator role and invite a user to that role.

Python
NodeJS
# pip install gql aiohttp
from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport
transport = AIOHTTPTransport(
url="YOUR_PANTHER_API_URL",
headers={"X-API-Key": "YOUR_API_KEY"},
)
client = Client(transport=transport, fetch_schema_from_transport=True)
create_user_admin = gql(
"""
mutation newAdminRole {
createRole (input: {
name: "user-admin"
permissions: [
UserRead
UserModify
OrganizationAPITokenRead
GeneralSettingsRead
]
})
{
role {
name
id
}
}
}
"""
)
invite_user = gql(
"""
mutation inviteUser($input: InviteUserInput!) {
inviteUser (input: $input) {
user {
id
email
}
}
}
"""
)
new_role_data = client.execute(
create_user_admin
)
print(f'new role ID is {new_role_data["createRole"]["role"]["id"]}')
response_data = client.execute(
invite_user,
variable_values= {
"input": {
"email": "[email protected]",
"givenName": "user",
"familyName": "admin",
"role": {
"kind": "ID",
"value": new_role_data["createRole"]["role"]["id"],
}
}
}
)
print(f'Successfully invited user {response_data["inviteUser"]["user"]["email"]} with role {new_role_data["createRole"]["role"]["name"]}.'
import { GraphQLClient, gql } from "graphql-request";
const client = new GraphQLClient(
"YOUR_PANTHER_API_URL",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
// `createUserAdmin` is a nickname for the query. You can fully omit it.
const createUserAdmin = gql`
mutation newAdminRole {
createRole(
input: {
name: "user-admin"
permissions: [
UserRead
UserModify
OrganizationAPITokenRead
GeneralSettingsRead
]
}
) {
role {
name
id
}
}
}
`;
// `inviteUser` is a nickname for the mutation. You can fully omit it.
const inviteUser = gql`
mutation inviteUser($input: InviteUserInput!) {
inviteUser(input: $input) {
user {
id
email
}
}
}
`;
(async () => {
try {
const newRoleData = await client.request(createUserAdmin);
const inviteUserOutput = await client.request(inviteUser, {
input: {
givenName: "user",
familyName: "admin",
role: {
kind: "ID",
value: newRoleData.createRole.role.id
}
}
});
console.log(
`Successfully invited user ${inviteUserOutput.inviteUser.user.email} with role ${newRoleData.createRole.role.name}.`
);
} catch (err) {
console.error(err);
}
})();