aws

package
v1.86.1 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: BSD-3-Clause Imports: 24 Imported by: 0

README

AWS IAM Adapter

Entity External IDs

The Entity External ID maps to AWS IAM SDK API calls. Unlike REST-based adapters, this adapter uses the AWS SDK v2 rather than constructing HTTP URLs directly.

Entity External ID AWS IAM API Call (List) AWS IAM API Call (Get) Description
User ListUsers GetUser IAM users
Group ListGroups GetGroup IAM groups
GroupMember GetGroup (returns .Users) - Group members (child of Group)
Role ListRoles GetRole IAM roles
IdentityProvider ListSAMLProviders - SAML identity providers
Policy ListPolicies GetPolicy IAM policies
RolePolicy ListAttachedRolePolicies - Policies attached to roles (child of Role)
UserPolicy ListAttachedUserPolicies - Policies attached to users (child of User)
GroupPolicy ListAttachedGroupPolicies - Policies attached to groups (child of Group)

Parent-Child Relationships

Child Entity Parent Entity Collection Attribute
GroupMember Group GroupName
GroupPolicy Group GroupName
RolePolicy Role RoleName
UserPolicy User UserName

Child entities iterate through their parent collection and fetch associated records per parent.

Unique ID Construction

  • Top-level entities use an id field constructed from their ARN.
  • Member/policy entities use a composite ID: {memberUniqueID}-{parentUniqueID}.

Notes

  • Supports cross-account access via STS AssumeRole with configured role ARNs.
  • Max page size is 1000, max resource accounts is 100.
  • The adapter uses the AWS SDK internally - the underlying endpoint is https://iam.amazonaws.com/.

Adding New Entity External IDs

Requires code changes. The adapter validates against ValidEntityExternalIDs and uses a switch statement in datasource.go to dispatch to entity-specific SDK call handlers.

To add a new entity:

  1. Add a constant in datasource.go (e.g., InstanceProfile string = "InstanceProfile").
  2. Add an entry to ValidEntityExternalIDs with the ARN attribute, unique name field, and parent relationship (if any).
  3. Create a handler struct in iam.go implementing the list/get SDK calls (following the pattern of UserHandler, GroupHandler, etc.).
  4. Add a case in the switch statement in GetPage to dispatch to the new handler via FetchEntities.
  5. If it's a child entity, set MemberOf and CollectionAttribute to configure parent iteration.
  6. Add tests.

Documentation

Index

Constants

View Source
const (
	User             string = "User"
	Group            string = "Group"
	GroupMember      string = "GroupMember"
	Role             string = "Role"
	IdentityProvider string = "IdentityProvider"
	Policy           string = "Policy"
	RolePolicy       string = "RolePolicy"
	UserPolicy       string = "UserPolicy"
	GroupPolicy      string = "GroupPolicy"

	UserID    string = "UserId"
	PolicyArn string = "PolicyArn"
	GroupID   string = "GroupId"
	AccountID string = "AccountId"

	SessionName = "SGNLSession"
)
View Source
const (

	// The maximum number of resource accounts that can be queried.
	MaxResourceAccounts = 100
)

Variables

View Source
var (
	// ValidEntityExternalIDs is a set of valid external IDs of entities that can be queried.
	ValidEntityExternalIDs = map[string]EntityInfo{
		User: {
			Identifiers: &Identifiers{
				ArnAttribute: "Arn",
				UniqueName:   "UserName",
			},
		},
		Group: {
			Identifiers: &Identifiers{
				ArnAttribute: "Arn",
				UniqueName:   "GroupName",
			},
		},
		Role: {
			Identifiers: &Identifiers{
				ArnAttribute: "Arn",
				UniqueName:   "RoleName",
			},
		},
		Policy: {
			Identifiers: &Identifiers{
				ArnAttribute: "Arn",
				UniqueName:   "PolicyName",
			},
		},
		IdentityProvider: {
			Identifiers: &Identifiers{
				ArnAttribute: "Arn",
			},
		},
		GroupPolicy: {
			CollectionAttribute: func() *string {
				var s = "GroupName"

				return &s
			}(),
			MemberOf: func() *string {
				var s = Group

				return &s
			}(),
		},
		GroupMember: {
			CollectionAttribute: func() *string {
				s := "GroupName"

				return &s
			}(),
			MemberOf: func() *string {
				s := Group

				return &s
			}(),
		},
		RolePolicy: {
			CollectionAttribute: func() *string {
				s := "RoleName"

				return &s
			}(),
			MemberOf: func() *string {
				s := Role

				return &s
			}(),
		},
		UserPolicy: {
			CollectionAttribute: func() *string {
				var s = "UserName"

				return &s
			}(),
			MemberOf: func() *string {
				s := User

				return &s
			}(),
		},
	}
)

Functions

func ArnToAccountID

func ArnToAccountID(entity *map[string]interface{}, entityType string) error

arnToAccountId adds the AccountID to the entity map using Entity Arn.

func EntityToObjects

func EntityToObjects(entity interface{}) (map[string]interface{}, error)

func FetchEntities

func FetchEntities[T any](
	ctx context.Context,
	handler any,
	opts *Options,
) ([]map[string]interface{}, int, *string, error)

FetchEntities is a generic function to fetch AWS entities. It retrieves a list of entities using the provided handler, converts them to a map format, and returns them along with an HTTP status code and a marker for the next set of results if available.

func NewAdapter

func NewAdapter(client Client) framework.Adapter[Config]

NewAdapter instantiates a new Adapter.

Types

type AccountCursor

type AccountCursor struct {
	Offset     int
	NextMarker *string
}

type Adapter

type Adapter struct {
	Client Client
}

Adapter implements the framework.Adapter interface to query pages of objects from datasources.

func (*Adapter) GetPage

func (a *Adapter) GetPage(ctx context.Context, request *framework.Request[Config]) framework.Response

GetPage is called by SGNL's ingestion service to query a page of objects from a datasource.

func (*Adapter) RequestPageFromDatasource

func (a *Adapter) RequestPageFromDatasource(
	ctx context.Context, request *framework.Request[Config],
) framework.Response

RequestPageFromDatasource requests a page of objects from a datasource.

func (*Adapter) ValidateGetPageRequest

func (a *Adapter) ValidateGetPageRequest(ctx context.Context, request *framework.Request[Config]) *framework.Error

ValidateGetPageRequest validates the fields of the GetPage Request.

type AttachedGroupPoliciesHandler

type AttachedGroupPoliciesHandler struct {
	Client *iam.Client
}

Implementation of AttachedGroupPolicies.

func (*AttachedGroupPoliciesHandler) List

type AttachedRolePoliciesHandler

type AttachedRolePoliciesHandler struct {
	Client *iam.Client
}

Implementation of AttachedRolePolicies.

func (*AttachedRolePoliciesHandler) List

type AttachedUserPoliciesHandler

type AttachedUserPoliciesHandler struct {
	Client *iam.Client
}

Implementation of AttachedUserPolicies.

func (*AttachedUserPoliciesHandler) List

type Auth

type Auth struct {
	// AccessKey is the access key to authenticate with the AWS.
	AccessKey string

	// SecretKey is the secret key to authenticate with the AWS.
	SecretKey string

	// Region is the AWS region to query.
	Region string
}

type Client

type Client interface {
	GetPage(ctx context.Context, request *Request) (*Response, *framework.Error)
}

Client is a client that allows querying the datasource which contains JSON objects.

func NewClient

func NewClient(
	client *http.Client,
	awsConfig *aws.Config,
	maxConcurrency int,
) (Client, error)

NewClient returns a Client to query the datasource.

type ClientConfig

type ClientConfig struct {
	AWSConfig *aws.Config
}

type Config

type Config struct {
	// Common configuration
	*config.CommonConfig

	// Region is the AWS region to query.
	Region string `json:"region"`

	// EntityConfig is a map containing the config required for each entity associated with this
	EntityConfig map[string]*EntityConfig `json:"entityConfig,omitempty"`

	// ResourceAccountRoles is a list of roleARNs.
	ResourceAccountRoles []string `json:"resourceAccountRoles,omitempty"`
}

Config is the configuration passed in each GetPage calls to the adapter. AWS Adapter configuration example: nolint: godot

{
  "resourceAccountRoles": [
    "arn:aws:iam::888111444333:role/Cross-Account-Assume-Admin",
    "arn:aws:iam::111111111111:role/Cross-Account-Assume-Admin"
  ],
  "region": "us-west-2",
  "requestTimeoutSeconds": 120
}

func (*Config) Validate

func (c *Config) Validate(_ context.Context) error

ValidateConfig validates that a Config received in a GetPage call is valid.

type Datasource

type Datasource struct {
	Client         *http.Client
	AWSConfig      *aws.Config
	MaxConcurrency int
}

func (*Datasource) GetIamClient

func (d *Datasource) GetIamClient(ctx context.Context, request *Request) (*iam.Client, *AccountCursor, *framework.Error)

GetIamClient returns an IAM client for the given request. If resource accounts are provided, it assumes the role for the account and returns the client. nolint:lll

func (*Datasource) GetPage

func (d *Datasource) GetPage(ctx context.Context, request *Request) (*Response, *framework.Error)

type EntityConfig

type EntityConfig struct {
	// PathPrefix is the path prefix to filter the entities.
	PathPrefix *string `json:"pathPrefix,omitempty"`
}

EntityConfig enables filtering of entities.

type EntityGetter

type EntityGetter[T any] interface {
	// The Get method retrieves the specified entity.
	//
	// Parameters:
	//
	//   ctx: Context for cancellation and deadlines.
	//   entity: Entity of type T to be retrieved.
	//
	// Returns:
	//
	//   T: Retrieved entity detail of type T.
	//   error: Error, if any.
	Get(ctx context.Context, entity T) (T, error)
}

EntityGetter is an interface for entities that require a Get operation.

type EntityInfo

type EntityInfo struct {
	// MemberOf Specifies the entity name to which the member belong.
	MemberOf *string
	// CollectionAttribute is the attribute that contains the collection name.
	CollectionAttribute *string
	// Identifiers contains the attributes that can be used to uniquely identify the entity.
	Identifiers *Identifiers
}

type EntityLister

type EntityLister[T any] interface {
	// The List method retrieves a list of entities with pagination support.
	//
	// Parameters:
	//
	//   ctx: Context for cancellation and deadlines.
	//   opts: Options to control the List operation, such as filtering and pagination.
	//
	// Returns:
	//
	//   []T: Slice of entities of type T.
	//   *string: Token for the next page.
	//   error: Error, if any.
	List(ctx context.Context, opts *Options) ([]T, *string, error)
}

EntityLister is an interface for entities that require a List operation.

type GroupHandler

type GroupHandler struct {
	Client *iam.Client
}

Implementation of EntityHandler for IAM Group.

func (*GroupHandler) Get

func (h *GroupHandler) Get(ctx context.Context, group types.Group,
) (types.Group, error)

func (*GroupHandler) List

func (h *GroupHandler) List(ctx context.Context, opts *Options,
) ([]types.Group, *string, error)

type GroupMemberHandler

type GroupMemberHandler struct {
	Client *iam.Client
}

Implementation of GroupMembers.

func (*GroupMemberHandler) List

func (h *GroupMemberHandler) List(ctx context.Context, opts *Options,
) ([]types.User, *string, error)

type IDPHandler

type IDPHandler struct {
	Client *iam.Client
}

Implementation of EntityHandler for IAM Identity Providers.

func (*IDPHandler) List

type Identifiers

type Identifiers struct {
	// ArnAttribute is the attribute that contains the Arn of the entity.
	// This is used to extract the AccountID.
	//
	// [Example: Arn, PolicyArn, etc.]
	ArnAttribute string

	// UniqueName of the AWS entity helps to get the entity.
	UniqueName string
}

type InputParams

type InputParams struct {
	PathPrefix *string // An optional prefix to filter the entities based on their path.
	MaxItems   *int32  // An optional limit on the number of entities to fetch.
	Marker     *string // An optional marker to indicate the starting point for the next set of results.
}

InputParams is the input parameters for List{Entity} from AWS.

type Options

type Options struct {
	InputParams

	EntityName         string  // The name of the entity for which the request is made.
	UniqueName         *string // Unique Name associated with the entity, used for identification.
	UniqueID           *string // Unique ID associated with the entity, used for identification.
	AccountIDRequested bool    // A flag indicating whether the Account ID is requested to be included in the response.
	IsMember           bool    // A flag indicating whether the entity is a member of another entity.
	MaxConcurrent      int     // The maximum number of concurrent requests to make.
}

Options contains adapter level options for fetching entities.

type PolicyHandler

type PolicyHandler struct {
	Client *iam.Client
}

Implementation of EntityHandler for IAM Policy.

func (*PolicyHandler) Get

func (h *PolicyHandler) Get(ctx context.Context, policy types.Policy,
) (types.Policy, error)

func (*PolicyHandler) List

func (h *PolicyHandler) List(ctx context.Context, opts *Options,
) ([]types.Policy, *string, error)

type Request

type Request struct {
	Auth

	// PageSize is the maximum number of objects to return from the entity.
	MaxItems int32

	// EntityExternalID is the external ID of the entity.
	// The external ID should match the API's resource name.
	EntityExternalID string

	// AccountIDRequested is a boolean that indicates whether the account ID is requested.
	AccountIDRequested bool

	// EntityConfig is a map containing the config required for each entity associated with this
	EntityConfig map[string]*EntityConfig

	// Cursor identifies the first object of the page to return, as returned by
	// the last request for the entity.
	// nil in the request for the first page.
	Cursor *pagination.CompositeCursor[string]

	// RequestTimeoutSeconds is the timeout duration for requests made to datasources.
	// This should be set to the number of seconds to wait before timing out.
	RequestTimeoutSeconds int

	// Ordered is a boolean that indicates whether the results should be ordered.
	Ordered bool

	// ResourceAccountRoles is a list of roleARNs.
	ResourceAccountRoles []string
}

Request is a request to the datasource.

type ResourceAccount

type ResourceAccount struct {
	// RoleARN is the ARN of the role to assume in the account.
	RoleARN string `json:"roleARN"`
}

type Response

type Response struct {
	// StatusCode is an HTTP status code.
	StatusCode int

	// RetryAfterHeader is the Retry-After response HTTP header, if set.
	RetryAfterHeader string

	// Objects is the list of items returned by the datasource.
	// May be empty.
	Objects []map[string]any

	// NextCursor is the cursor that identifies the first object of the next page.
	// nil if this is the last page in this full sync.
	NextCursor *pagination.CompositeCursor[string]
}

Response is a response returned by the datasource.

type RoleHandler

type RoleHandler struct {
	Client *iam.Client
}

Implementation of EntityHandler for IAM Role.

func (*RoleHandler) Get

func (h *RoleHandler) Get(ctx context.Context, role types.Role) (types.Role, error)

func (*RoleHandler) List

func (h *RoleHandler) List(ctx context.Context, opts *Options,
) ([]types.Role, *string, error)

type UserHandler

type UserHandler struct {
	Client *iam.Client
}

Implementation of EntityHandler for IAM User.

func (*UserHandler) Get

func (h *UserHandler) Get(ctx context.Context, user types.User) (types.User, error)

func (*UserHandler) List

func (h *UserHandler) List(ctx context.Context, opts *Options,
) ([]types.User, *string, error)

Jump to

Keyboard shortcuts

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