Contains functions for interacting with the CyberArk Identity SCIM Interface for Privileged Access Management (Self Hosted or Privilege Cloud).
import (
"github.com/strick-j/cybr_pam_scim"
"github.com/strick-j/cybr_pam_scim/types"
)
All functions are documented with example usage in their respective go files. General flow for usage will be:
- Obtain oauth2.token through authentication
- Provide existing Bearer token
- Use Client Credential Workflow via
OauthCredClient
- Use Resource Owner Workflow via
OauthResourceOwner
- Establish Service with Oauth2 Token
- Utilize Service to interact User, Group, Container, or Privileged Data functions
Function | Input | Output |
---|---|---|
OauthCredClient |
Client Id, Client secret, Application Id, Identity URL | oauth2.token or error |
OauthResourceOwner |
Client Id, Client secret,, Application Id, Identity URL, Resource Owner Username, Resource Owner Password | oauth2.token or error |
Function | Input | Output |
---|---|---|
NewService |
Identity URL, Identity API Endpoint, Identity API Version, Authentication Token | Service struct containing http.Client |
Function | Input | Output | PVWA 12.2+ Required |
---|---|---|---|
GetUsers |
- | types.Users or error | |
GetUsersIndex |
Start Index and Count | types.Users or error | X |
GetUsersSort |
Sort By and Sord Order | types.Users or error | X |
GetUserById |
User Id | types.User or error | X |
GetUserByFilter |
Filter Type and Filter Query | types.User or error | |
AddUser |
types.User | types.User or error | X |
UpdateUser |
types.User | types.User or error | |
DeleteUser |
User Id | error |
Notes:
- GetUsersByFilter: Filter Query is case sensitive
- UpdateUser: User Id must be included in the type.User struct for Update Safe permissions as the API endpoint is generated based on this info.
Function | Input | Output | PVWA 12.2+ Required |
---|---|---|---|
GetGroups |
- | types.Groups or error | |
GetGroupsIndex |
Start Index and Count | types.Groups or error | X |
GetGroupsSort |
Sort By and Sord Order | types.Groups or error | X |
GetGroupById |
Group Id | types.Group or error | X |
GetGroupByFilter |
Filter Type and Filter Query | types.Group or error | |
AddGroup |
types.Group | types.Groupr or error | |
UpdateGroup |
types.Group | types.Group or error | X |
DeleteGroup |
Group Id | error |
Notes:
- GetGroupsByFilter: Filter Query is case sensitive
- UpdateGroup: Group Id must be included in the type.Group struct for Update Safe permissions as the API endpoint is generated based on this info.
Function | Input | Output | PVWA 12.2+ Required |
---|---|---|---|
GetSafes |
- | types.Containers or error | |
GetSafesIndex |
Start Index and Count | types.Containers or error | X |
GetSafesSort |
Sort By and Sord Order | types.Containers or error | X |
GetSafeByName |
Safe Name | types.Container or error | X |
GetSafeByFilter |
Filter Type and Filter Query | types.Container or error | |
AddSafe |
types.Container | types.Container or error | |
UpdateSafe |
types.Container | types.Container or error | X |
DeleteSafe |
Safe Name | error |
Notes:
- General: Safe functions utilize Safe Name instead of Id although both fields are typically the same in the returned types.Container struct.
- GetSafeByFilter: Filter Query is case sensitive
Function | Input | Output | PVWA 12.2+ Required |
---|---|---|---|
GetSafePermissions |
- | types.ContainerPermissions or error | |
GetSafePermissionsIndex |
Start Index and Count | types.ContainerPermissions or error | X |
GetSafePermissionsSort |
Sort By and Sord Order | types.ContainerPermissions or error | X |
GetSafePermissionsByName |
Safe Name and User Name | types.ContainerPermission or error | X |
GetSafePermissionsByFilter |
Filter Type and Filter Query | types.ContainerPermission or error | |
AddSafePermissions |
types.ContainerPermission | types.Container or error | X |
UpdateSafePermissions |
types.ContainerPermission | types.Container or error | |
DeleteSafePermissions |
Safe Name and User or Group Name | error |
Notes:
- GetSafePermissionsByFilter: Filter Query is case sensitive
- UpdateSafePermissions: User Display Name and Safe Name must be included in the type.ContainerPermissions struct for Update Safe permissions as the API endpoint is generated based on this info.
- DeleteSafePermissions: Deletes a User or Group membership to a safe. You must provide either a User or Group Name in addition to the Safe Name.
Function | Input | Output | PVWA 12.2+ Required |
---|---|---|---|
GetPrivilegedData |
- | types.PrivilegedDatas or error | |
GetPrivilegedDataIndex |
Start Index and Count | types.PrivilegedDatas or error | X |
GetPrivilegedDataSort |
Sort By and Sord Order | types.PrivilegedDatas or error | X |
GetPrivilegedDataById |
Privileged Data Id | types.PrivilegedData or error | X |
GetPrivilegedDataByFilter |
Filter Type and Filter Query | types.PrivilegedData or error | |
AddPrivilegedData |
types.PrivilegedData | types.PrivilegedData or error | X |
UpdatePrivilegedData |
types.PrivilegedData | types.PrivilegedData or error | |
ModifyPrivilegedData |
types.PrivilegedData | types.PrivilegedData or error | |
DeletePrivilegedData |
Privileged Data Id | error |
Notes:
- GetPrivilegedDataByFilter: Filter Query is case sensitive
- UpdatePrivilegedData: The Privileged Data Id must be included in the types.PrivilegedData struct as the API endpoint is generated based on this info.
- ModifyPrivilegedData: The Privileged Data Id must be included in the types.PrivilegedData struct as the API endpoint is generated based on this info.
- ModifyPrivilegedData: The struct required to modify Privileged Data is uniqe in that it adds a nested Operations struct which contains the operations information (e.g. replace). Review the official CyberArk documentation for more info.
- Filter Query is typically case sensitive.
- Always include the object Id in structs when performing updates as it is frequently used in generating the API Endpoint.
- Get, Get Index, Get Sort, and Update Object by Name or ID may not work with PVWA Versions below 12.2
package main
////// Client Credentials Overview ///////////////////////////////////////////////////
//
// This example leverages a client_id and client_secret to authenticate
// to the SCIM Oauth2 Endpoint (https://<ScimUrl>/ouath2/token/<AppId>).
//
// If Authentication is successful a clientCredentials.Oauth2 token is returned.
// The returned Oauth2 token is then utilized to establish a Service
// based on thehttps client module to interact with the SCIM API.
//
/////////////////////////////////////////////////////////////////////////////
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/spf13/viper"
cybr_pam_scim "github.com/strick-j/cybr_pam_scim/pkg/cybr_pam_scim"
)
func main() {
// Set the file name of the configuration file
viper.SetConfigName("config")
// Set the path to look for configuration file
viper.AddConfigPath(".")
// Enable VIPER to read Environment Variables
viper.AutomaticEnv()
viper.SetConfigType("yml")
if err := viper.ReadInConfig(); err != nil {
fmt.Printf("Error reading config file, %s", err)
}
// Read environment variables from config.yml and set them with type assertion
clientId, ok := viper.Get("IDENTITY.CLIENT_ID").(string)
clientSecret, ok := viper.Get("IDENTITY.CLIENT_SECRET").(string)
clientAppId, ok := viper.Get("IDENTITY.APP_ID").(string)
clientUrl, ok := viper.Get("IDENTITY.URL").(string)
// If type assert is not valid it will throw an error
if !ok {
log.Fatalf("Invalid type assertion")
}
// Obtain an auth token with the provided credentials and endpoint parameters
// The Oauth2 Token format should be the following:
// type Token struct {
// AccessToken string `json:"access_token"`
// TokenType string `json:"token_type,omitempty"`
// RefreshToken string `json:"refresh_token,omitempty"`
// Expiry time.Time `json:"expiry,omitempty"`
// }
// Note: Client Credentials token does not contain a refresh token
authToken, err := cybr_pam_scim.OauthCredClient(clientId, clientSecret, clientAppId, clientUrl)
if err != nil {
log.Fatalf("Authentication Failed. %s", err)
}
// Marshal the authToken for display purposes
authTokenJSON, err := json.MarshalIndent(authToken, "", " ")
if err != nil {
log.Fatalf(err.Error())
}
// Print the auth Token
fmt.Printf("Auth Token JSON Response %s\n", string(authTokenJSON))
// Utilize the returned oauth2.Token to create a service that leverages the
// the https client module
s := cybr_pam_scim.NewService(clientUrl, "scim", "v2", false, authToken)
// Utilize the returned service to interact with the SCIM API
// In this example all users are being retrieved and the DisplayName of the
// first user in the struct is being displayed
Users, err := s.GetUsers(context.Background())
if err != nil {
fmt.Printf("Error Retrieving users")
}
// Do something with the Users struct
fmt.Printf(Users.Resources[1].DisplayName)
}
If there is a security concern or bug discovered, please responsibly disclose all information to joe (dot) strickland (at) cyberark (dot) com.
Pull Requests are currently being accepted. Please read and follow the guidelines laid out in CONTRIBUTING.md.