-
Notifications
You must be signed in to change notification settings - Fork 172
CLI Reference
Principal Mapper provides a command-line interface to all of its core functions. This page details all the different operations and parameters you can use.
You can pass credentials to PMapper the same as you do when using the AWS CLI. If you call aws --profile <profile> configure
and provide access keys for an IAM User, you can then use that profile in PMapper as in pmapper --profile <profile> ...
. If you don't specify a profile, PMapper looks for a default profile, AWS_*
environment variables, the EC2 instance metadata service, etc. to try to locate and use credentials the same as the AWS CLI does.
Credentials are necessary for the operations that go query the AWS API to gather information on an account/organization (graph
and orgs
subcommands) but you can instead use --account
for other operations (argquery
, query
, analysis
, visualize
). This saves time, because otherwise PMapper will call the AWS STS API to figure out which account the credentials it's using belongs to.
All operations for creating, listing, and displaying information about Graphs are available with the graph
subcommand in the CLI. For PMapper, a Graph is a model of the different IAM Users and Roles (Principals) and how they are able to access each other.
The graph
subcommand itself has a set of subcommands for its different operations. The create
subcommand does the work of creating a Graph. This requires access to an IAM User/Role that is authorized to read data in the account (the ReadOnlyAccess
managed policy works for this). There are additional parameters you can specify that affect the creation process:
-
--ignore-orgs
: PMapper checks to see if the account that it is creating a Graph for is a member of an AWS organization. Note that the organization has to be stored first (see theorgs
subcommand). If so, it will apply SCPs during the edge identification process (avoids things like EC2-related edges when the account has an SCP that blocks all EC2 access). When this flag is specified, SCPs will not apply to edge identification. -
--include-regions
|--exclude-regions
: PMapper allows one or the other of these arguments to list regions to include or exclude when pulling data from the AWS API. If you know all the account's resources are in a set of regions, then--include-regions
can help reduce the time that creating a Graph takes. If you know that some regions are disabled but need a thorough check,--exclude-regions
lets you ignore those extra regions. -
--include-services
|--exclude-services
: PMapper pulls data from several services when creating a Graph. You can specify one or the other of the arguments to include/exclude which services are looked at for creating Edges (does not apply to resource-policy gathering).
Here's an example:
$ pmapper graph create --exclude-regions af-south-1 ap-east-1 eu-south-1 me-south-1
The list
subcommand prints the different AWS account IDs that PMapper has a Graph for.
The display
subcommand lists out high-level statistics about the Graph that PMapper stored for the given AWS account. Note that the --account
global parameter will work here.
The query
subcommand lets you create "plain-English" queries to run against Graph data. You can see if a given IAM User/Role is able to make a given AWS API call, or if that user can pivot its way into another IAM User/Role that can make the API call. There is another wiki page that has a reference for the syntax of those queries.
There are additional arguments you can use:
-
-s
|--skip-admin
: When running a query on multiple principals in an account, this flag skips the IAM Users/Roles that are marked as admins. Note that non-admins that can pivot to admins are still included. -
-u
|--include-unauthorized
: This flag will include output saying if a principal is not authorized or able to make a given API call. By default, PMapper just reports the principals that can. -
--with-resource-policy
|--resource-policy-text
: These parameters, of which only one can be specified at a time, set the resource policy to include as part of the authorization check.--with-resource-policy
will automatically identify the resource in the query and load that policy (has to be one of the cached policies, PMapper currently supports IAM, KMS, S3, SNS, and SQS). The other arg,--resource-policy-text
, lets you type out a resource policy to include in the authorization check (should support all AWS). -
--resource-owner
: For queries where the resource ARN does not specify an account (i.e. for S3 buckets/objects), this argument takes the account ID of the owner of the resource. -
--session-policy
: This parameter lets you include a session policy (from the AWS STS APIs) as part of the authorization check. Note that it only applies to the initial principal and is not passed along to other principals reached via Edges. -
--scps
: This flag will cause the authorization check to include any Service Control Policies (SCPs), assuming the account is part of an organization and the organization's data has been obtained (orgs
subcommand).
When calling the query
subcommand, you have to specify the additional arguments and then finally the actual query. The query should be enclosed in a string that will not expand wildcards (*
) or instances of dollar-signs ($
) in your shell. For example, when I use Bash to work with PMapper, I enclose the query in single-quotes/apostrophes ('<query>'
). Here's an example:
$ pmapper --account 000000000000 query -s 'who can do lambda:UpdateFunctionCode with arn:aws:lambda:us-west-2:000000000000:function:*'
The argquery
subcommand creates parameterized queries to run against Graph data. It operates the same as the query
subcommand, but takes arguments to specify action/resource/condition rather than interpreting a query. The parameters are:
-
--principal
: This should be a string to match one or more IAM Users/Roles in the given account. Note that it takes the "searchable name" of the users/roles soarn:aws:iam::000000000000:user/admins/Mary
needs to be referred to asuser/Mary
. By default this value is set to*
, which runs the query against all principals in the account, so you can exclude this argument altogether to just query all principals. -
--action
: This argument specifies the action to do authorization checks against. For example, to launch an EC2 instance, you wantec2:RunInstances
. -
--resource
: This argument specifies the resource to do authorization checks against, which should be an ARN for a specific resource. This defaults to a wildcard*
value, and the argument can be excluded to default to that value. -
--condition
: This specifies a key-value pair, separated with an equals-sign (=
), for a condition context key and its value. This parameter can be invoked multiple times for as many conditions as necessary. -
--preset
: This specifies a preset query to run rather than an authorization check. -
-s
|--skip-admin
: When running a query on multiple principals in an account, this flag skips the IAM Users/Roles that are marked as admins. Note that non-admins that can pivot to admins are still included. -
-u
|--include-unauthorized
: This flag will include output saying if a principal is not authorized or able to make a given API call. By default, PMapper just reports the principals that can. -
--with-resource-policy
|--resource-policy-text
: These parameters, of which only one can be specified at a time, set the resource policy to include as part of the authorization check.--with-resource-policy
will automatically identify the resource in the query and load that policy (has to be one of the cached policies, PMapper currently supports IAM, KMS, S3, SNS, and SQS). The other arg,--resource-policy-text
, lets you type out a resource policy to include in the authorization check (should support all AWS). -
--resource-owner
: For queries where the resource ARN does not specify an account (i.e. for S3 buckets/objects), this argument takes the account ID of the owner of the resource. -
--session-policy
: This parameter lets you include a session policy (from the AWS STS APIs) as part of the authorization check. Note that it only applies to the initial principal and is not passed along to other principals reached via Edges. -
--scps
: This flag will cause the authorization check to include any Service Control Policies (SCPs), assuming the account is part of an organization and the organization's data has been obtained (orgs
subcommand).
Here's an example:
$ pmapper --account 000000000000 argquery \
--principal 'user/only_launch_with_mfa'
--action 'ec2:RunInstances' \
--condition 'aws:MultiFactorAuthAge=1' \
--condition 'aws:MultiFactorAuthPresent=true'
PMapper includes a read-evaluate-print-loop (REPL) feature for running multiple queries against a single account, keeping that account's Graph and relevant caches in-memory. It comes with its own help-output to explain how to use it.
The analysis
subcommand generates either a Markdown-formatted report or a JSON object with findings derived by analyzing the Graph. Note that this writes to stdout, so redirect to save it as a file. The parameter controlling the output type is --output-type
which takes either text
or json
as a value.
PMapper's visualize
subcommand creates visualizations of Graph data and creates files (naming convention includes account ID, file extension, and visualization type). This supports creating SVGs, PNGs, DOTs, and GraphML files. The arguments are:
-
--filetype
: This specifies which file type to output, and accepts the values:svg
,png
,dot
, andgraphml
. -
--only-privesc
: This flag makes PMapper generate an image that only includes admin Nodes and the Nodes that can escalate privileges by accessing admin Nodes.
Much like the graph
subcommand, PMapper has an orgs
subcommand that itself has subcommands for creating/listing/displaying/updating organizations data.
The create
subcommand pulls data from AWS Organizations to create a local OrganizationTree
object that represents an organization. This operation has to be run from the management account (formerly referred to as the master account) of the organization, and the user/role being used to call the AWS API has to be authorized for read-access to AWS Organizations. This operation takes no additional arguments.
The list
subcommand prints a list of all the organizations that PMapper has stored, by their organization ID.
The display
subcommand prints out all data stored on an given organization. It takes an argument, --org
, that should be the organization ID of the organization to display.
The update
subcommand goes to all the stored Graphs and adds organizations metadata to them. This is necessary for running argquery
/query
to include SCPs during authorization checks. It takes the same --org
argument as the display
subcommand, the organization ID to update graphs for. Note that if you pull organizations data first, then pull a Graph, the Graph will have that association without needing to run orgs update
.