scim

package
v0.0.0-...-abe0a37 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package scim implements a client for GitHub's SCIM REST API for Enterprise Managed Users (EMU).

See: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/scim

Index

Examples

Constants

View Source
const (
	// UserSchema is the SCIM schema URN for User resources.
	UserSchema = "urn:ietf:params:scim:schemas:core:2.0:User"
	// GroupSchema is the SCIM schema URN for Group resources.
	GroupSchema = "urn:ietf:params:scim:schemas:core:2.0:Group"
	// PatchOpSchema is the SCIM schema URN used for PATCH operations.
	PatchOpSchema = "urn:ietf:params:scim:api:messages:2.0:PatchOp"
)

Variables

This section is empty.

Functions

func IsStatus

func IsStatus(err error, status int) bool

IsStatus reports whether err contains an APIError with the given HTTP status.

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
	// SCIMType is the RFC 7644 "scimType" detail code (e.g. "uniqueness"),
	// when the server included one. It is empty if the response body did
	// not carry a SCIM error detail.
	SCIMType   string
	RequestURL string
	// contains filtered or unexported fields
}

APIError describes an error response from the GitHub SCIM API.

Example
package main

import (
	"context"
	"errors"
	"net/http"

	"github.com/eroullit/gh-scim/scim"
)

func main() {
	client, err := scim.NewClient("octo-enterprise")
	if err != nil {
		return
	}

	_, err = client.GetUser(context.Background(), "scim-user-id")
	var apiErr *scim.APIError
	if errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusNotFound {
		// Handle a missing SCIM user.
	}
}

func (*APIError) Error

func (e *APIError) Error() string

Error returns a human-readable API error.

func (*APIError) Unwrap

func (e *APIError) Unwrap() error

Unwrap returns the underlying transport error.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client talks to the GitHub SCIM API for a single enterprise. A Client is safe for concurrent use when its configured Doer is safe for concurrent use. The default Doer is safe for concurrent use.

func NewClient

func NewClient(enterprise string, options ...Option) (*Client, error)

NewClient builds a SCIM client for the given enterprise slug.

Without options, NewClient uses go-gh's normal host and token resolution. The resolved host must be GitHub.com or a GHE.com tenancy; GitHub Enterprise Server does not support this enterprise SCIM API.

Example
package main

import (
	"context"
	"os"
	"time"

	"github.com/eroullit/gh-scim/scim"
)

func main() {
	client, err := scim.NewClient(
		"octo-enterprise",
		scim.WithHost("github.com"),
		scim.WithToken(os.Getenv("SCIM_TOKEN")),
		scim.WithTimeout(30*time.Second),
	)
	if err != nil {
		return
	}

	users, err := client.ListUsers(context.Background(), scim.ListParams{
		Filter: `userName eq "octocat"`,
	})
	if err != nil {
		return
	}
	_ = users.Resources
}

func (*Client) AddGroupMembers

func (c *Client) AddGroupMembers(ctx context.Context, scimGroupID string, memberIDs ...string) (*Group, error)

AddGroupMembers is a convenience wrapper around PatchGroup that adds the given member ids to a group without affecting existing members.

func (*Client) CreateGroup

func (c *Client) CreateGroup(ctx context.Context, g Group) (*Group, error)

CreateGroup provisions a new SCIM group for the enterprise. Members referenced by Value must already exist as provisioned users.

POST /scim/v2/enterprises/{enterprise}/Groups

func (*Client) CreateUser

func (c *Client) CreateUser(ctx context.Context, u User) (*User, error)

CreateUser provisions a new SCIM user for the enterprise.

POST /scim/v2/enterprises/{enterprise}/Users

func (*Client) DeleteGroup

func (c *Client) DeleteGroup(ctx context.Context, scimGroupID string) error

DeleteGroup deletes a SCIM group from the enterprise.

DELETE /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}

func (*Client) DeleteUser

func (c *Client) DeleteUser(ctx context.Context, scimUserID string) error

DeleteUser hard-deprovisions (permanently suspends) a user. This action is irreversible; the user must be provisioned again as a new user afterwards.

DELETE /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}

func (*Client) GetGroup

func (c *Client) GetGroup(ctx context.Context, scimGroupID string) (*Group, error)

GetGroup retrieves a single SCIM group by its GitHub-assigned SCIM group id.

GET /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}

func (*Client) GetUser

func (c *Client) GetUser(ctx context.Context, scimUserID string) (*User, error)

GetUser retrieves a single SCIM user by its GitHub-assigned SCIM user id.

GET /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}

func (*Client) ListGroups

func (c *Client) ListGroups(ctx context.Context, params ListParams) (*ListResponse[Group], error)

ListGroups lists provisioned SCIM groups for the enterprise.

GET /scim/v2/enterprises/{enterprise}/Groups

func (*Client) ListUsers

func (c *Client) ListUsers(ctx context.Context, params ListParams) (*ListResponse[User], error)

ListUsers lists provisioned SCIM users for the enterprise.

GET /scim/v2/enterprises/{enterprise}/Users

func (*Client) PatchGroup

func (c *Client) PatchGroup(ctx context.Context, scimGroupID string, ops ...PatchOperation) (*Group, error)

PatchGroup updates individual attributes of an existing group, such as its displayName or membership list.

PATCH /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}

func (*Client) PatchUser

func (c *Client) PatchUser(ctx context.Context, scimUserID string, ops ...PatchOperation) (*User, error)

PatchUser updates individual attributes of an existing user.

PATCH /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}

func (*Client) RemoveGroupMembers

func (c *Client) RemoveGroupMembers(ctx context.Context, scimGroupID string, memberIDs ...string) (*Group, error)

RemoveGroupMembers is a convenience wrapper around PatchGroup that removes the given member ids from a group.

func (*Client) ReplaceGroup

func (c *Client) ReplaceGroup(ctx context.Context, scimGroupID string, g Group) (*Group, error)

ReplaceGroup replaces all of an existing group's attributes, including its membership list. Any attribute not provided is removed.

PUT /scim/v2/enterprises/{enterprise}/Groups/{scim_group_id}

func (*Client) ReplaceUser

func (c *Client) ReplaceUser(ctx context.Context, scimUserID string, u User) (*User, error)

ReplaceUser replaces all of an existing user's attributes. Any attribute not provided is removed, matching the semantics of a SCIM PUT.

PUT /scim/v2/enterprises/{enterprise}/Users/{scim_user_id}

func (*Client) SetUserActive

func (c *Client) SetUserActive(ctx context.Context, scimUserID string, active bool) (*User, error)

SetUserActive is a convenience wrapper around PatchUser to soft-deprovision (active=false) or reactivate (active=true) a user.

type Doer

type Doer interface {
	DoWithContext(ctx context.Context, method, path string, body io.Reader, response any) error
}

Doer executes a REST request. Callers can implement Doer to provide custom authentication, routing, retries, or test doubles.

type Email

type Email struct {
	Value   string `json:"value"`
	Type    string `json:"type,omitempty"`
	Primary bool   `json:"primary"`
}

Email represents a single email entry for a SCIM user.

type Group

type Group struct {
	Schemas     []string `json:"schemas,omitempty"`
	ID          string   `json:"id,omitempty"`
	ExternalID  string   `json:"externalId,omitempty"`
	DisplayName string   `json:"displayName,omitempty"`
	Members     []Member `json:"members,omitempty"`
	Meta        *Meta    `json:"meta,omitempty"`
}

Group represents a SCIM enterprise group resource.

type GroupRef

type GroupRef struct {
	Value   string `json:"value,omitempty"`
	Ref     string `json:"$ref,omitempty"`
	Display string `json:"display,omitempty"`
}

GroupRef references a group a user belongs to, as returned in a user's resource representation.

type ListParams

type ListParams struct {
	// Filter is a SCIM filter expression, e.g. `userName eq "octocat"`.
	Filter string
	// StartIndex is the 1-based index of the first result to return.
	StartIndex int
	// Count is the number of results to return per page.
	Count int
	// ExcludedAttributes, when set to "members", speeds up group listing by
	// omitting membership information from the response.
	ExcludedAttributes string
}

ListParams holds common pagination/filter query parameters supported by the SCIM list endpoints.

type ListResponse

type ListResponse[T any] struct {
	Schemas      []string `json:"schemas"`
	TotalResults int      `json:"totalResults"`
	ItemsPerPage int      `json:"itemsPerPage"`
	StartIndex   int      `json:"startIndex"`
	Resources    []T      `json:"Resources"`
}

ListResponse is the generic SCIM ListResponse envelope returned by the Users and Groups list endpoints.

type Member

type Member struct {
	Value       string `json:"value"`
	Ref         string `json:"$ref,omitempty"`
	Display     string `json:"display,omitempty"`
	DisplayName string `json:"displayName,omitempty"`
}

Member represents a single member entry within a SCIM group.

type Meta

type Meta struct {
	ResourceType string `json:"resourceType,omitempty"`
	Created      string `json:"created,omitempty"`
	LastModified string `json:"lastModified,omitempty"`
	Location     string `json:"location,omitempty"`
}

Meta holds SCIM resource metadata.

type Name

type Name struct {
	Formatted  string `json:"formatted,omitempty"`
	FamilyName string `json:"familyName"`
	GivenName  string `json:"givenName"`
	MiddleName string `json:"middleName,omitempty"`
}

Name represents the SCIM "name" complex attribute for a user.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option configures a Client.

func WithDoer

func WithDoer(doer Doer) Option

WithDoer supplies a complete request executor. It cannot be combined with WithHost, WithToken, WithTimeout, or WithTransport because those options configure the default go-gh-backed Doer.

func WithHost

func WithHost(host string) Option

WithHost sets the GitHub.com or GHE.com hostname used for SCIM requests. Both SUBDOMAIN.ghe.com and api.SUBDOMAIN.ghe.com are accepted for GHE.com.

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the timeout applied to each request by the default go-gh-backed Doer.

func WithToken

func WithToken(token string) Option

WithToken sets the personal access token used to authenticate SCIM requests.

func WithTransport

func WithTransport(transport http.RoundTripper) Option

WithTransport sets the HTTP transport used by the default go-gh-backed Doer.

type PatchOperation

type PatchOperation struct {
	Op    string `json:"op"`
	Path  string `json:"path,omitempty"`
	Value any    `json:"value,omitempty"`
}

PatchOperation represents a single SCIM PATCH operation.

type PatchRequest

type PatchRequest struct {
	Schemas    []string         `json:"schemas"`
	Operations []PatchOperation `json:"Operations"`
}

PatchRequest is the body sent to SCIM PATCH endpoints.

func NewPatchRequest

func NewPatchRequest(ops ...PatchOperation) PatchRequest

NewPatchRequest builds a PatchRequest wrapping the given operations with the required PatchOp schema.

type Role

type Role struct {
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"`
	Value   string `json:"value"`
	Primary bool   `json:"primary,omitempty"`
}

Role represents a role assigned to a SCIM user (e.g. user, enterprise_owner, billing_manager, guest_collaborator).

type User

type User struct {
	Schemas     []string   `json:"schemas,omitempty"`
	ID          string     `json:"id,omitempty"`
	ExternalID  string     `json:"externalId,omitempty"`
	Active      *bool      `json:"active,omitempty"`
	UserName    string     `json:"userName,omitempty"`
	Name        *Name      `json:"name,omitempty"`
	DisplayName string     `json:"displayName,omitempty"`
	Emails      []Email    `json:"emails,omitempty"`
	Roles       []Role     `json:"roles,omitempty"`
	Groups      []GroupRef `json:"groups,omitempty"`
	Meta        *Meta      `json:"meta,omitempty"`
}

User represents a SCIM enterprise user resource.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL