Advanced RBAC: Governing Access to Processes and Accounts, Part 2

Overview

Welcome to Part 2 of Advanced RBAC: Governing Access to Processes and Accounts!

In Part 1, we wrote a composition declaring an S3 bucket and an RBAC policy composition governing accounts and processes. We also showed how to apply the policy to the Conductor, enable a new user, and switch users.

Here in Part 2, we’ll run a composition as one user, check the process status as a second user, and kill the process as a third user. We’ll also explain how rules interact at the process and account levels.

Part 1 is a prerequisite for this exercise, so if you haven’t had a chance to complete it yet, go ahead and check it out.

Let’s Go!

Running the Composition

Before we begin, did you remember to download and modify the S3BucketWithPolicy.lw composition? If not, go back and follow these steps to edit it. You’ll need to replace the dummy text with your AWS account ID and desired bucket name before proceeding.

OK, it’s time for alice to run the composition! Since alice has secOps permissions, she can run a composition in the default account. Make sure you include the -a option so we can give the process an alias of bucketProcess:

fugue run S3BucketWithPolicy.lw -a bucketProcess

You’ll see output like this:

[ fugue run ] Running /Users/main-user/projects/S3BucketWithPolicy.lw

Run Details:
    Account: default
    Alias: bucketProcess

Compiling Ludwig file /Users/main-user/projects/S3BucketWithPolicy.lw
[ OK ] Successfully compiled. No errors.

Uploading compiled Ludwig composition to S3...
[ OK ] Successfully uploaded.

Requesting the Conductor to create and run process based on composition ...
[ DONE ] Process created and running.


State    Updated    Created    Account              FID                                   Alias          Flags      Last Message  Next Command
-------  ---------  ---------  -------------------  ------------------------------------  -------------  -------  --------------  --------------
Running  6:56pm     6:56pm     fugue-1507311378131  bc2e3ca6-6662-45ff-a4e4-bebbfeadbc8d  bucketProcess  -e                       run

[ HELP ] Run the "fugue status" command to view details and status for all Fugue processes.

Great! alice has successfully run the bucketProcess composition. We named the bucket fugue-docs-bucket-repo, but yours will have a different name. Give the Conductor a moment to create the bucket, and take a look at it in the S3 Management Console.

A successfully created S3 bucket.

A successfully created S3 bucket.

So far, so good! If you click on “Permissions,” then “Bucket Policy,” you’ll see the exact policy in the S3BucketWithPolicy.lw composition.

The IAM policy on the S3 bucket.

The IAM policy on the S3 bucket.

Now we have proof that alice, as a member of the secOps group, can run a composition in the default account. Since she has full permissions to bucketProcess, let’s test it out with a couple process management commands.

First, we’ll suspend the process. We’ll use the -y flag to suppress the confirmation dialog:

fugue suspend -y bucketProcess

You’ll see output like this:

[ fugue suspend ] Suspending process with alias: bucketProcess

Requesting the Conductor to suspend process ...
[ DONE ] Process with alias: bucketProcess is being suspended.

[ HELP ] Run the 'fugue status' command to view details and status of this process suspension.

And if you execute fugue status, you can confirm that the process has been suspended:

fugue status

Note that the process “State” has changed:

Fugue Status Report for main-user/xxxxxxxxxxxx - Sun Dec 17 2017 7:30pm

State      Updated    Created    Account              FID                                   Alias          Flags    Last Message    Next Command
---------  ---------  ---------  -------------------  ------------------------------------  -------------  -------  --------------  --------------
Suspended  7:29pm     6:56pm     fugue-1507311378131  bc2e3ca6-6662-45ff-a4e4-bebbfeadbc8d  bucketProcess  -e       SUCCEEDED

Looking good! Let’s resume the process now, again with the -y flag to suppress the confirmation dialog:

fugue resume -y bucketProcess

You’ll see output like this:

[ fugue resume ] Resuming process with alias: bucketProcess

Requesting the Conductor to resume process ...
[ DONE ] Process with alias: bucketProcess is being resumed.

[ HELP ] Run the "fugue status" command to view details and status of this process resume.

If we run fugue status again in a moment, we’ll see that bucketProcess has returned to Running state:

Fugue Status Report for main-user/xxxxxxxxxxxx - Sun Dec 17 2017 7:33pm

State    Updated    Created    Account              FID                                   Alias          Flags    Last Message    Next Command
-------  ---------  ---------  -------------------  ------------------------------------  -------------  -------  --------------  --------------
Running  7:32pm     6:56pm     fugue-1507311378131  bc2e3ca6-6662-45ff-a4e4-bebbfeadbc8d  bucketProcess  -e       SUCCEEDED

As expected, alice (as a member of secOps) has full control over bucketProcess.

What if another SecOps team member needs read/write access to the bucket? Alice can adjust the IAM policy in the S3BucketWithPolicy.lw composition by adding the new AWS account ID on line 19. Then, she can execute fugue update to update bucketProcess with the modified composition. Since only members of secOps have permission to update the process, and only alice has permission to modify the users in secOps, the bucket’s security is bolstered by multiple layers of access control.

Enabling the Bob User

We need to ensure bob has status-only privileges for bucketProcess. First, though, we need to enable the user by generating a secret for him.

We gave alice full RBAC permissions, so while she’s still the active user, execute the fugue policy generate-secret command:

fugue policy generate-secret bob

As before, you can manually cut and paste bob‘s credentials into the credentials file. But since we need to switch the active user to bob anyway, let’s save ourselves a step and use the fugue user set command with the -p flag to save his credentials in a new profile. Grab the secret from the output of the last command and execute the following command:

fugue user set -p bob bob <secret>

Go ahead and enter y when the CLI asks if you want to continue.

When the command is complete, feel free to check out the credentials file (cat credentials) to see the new [bob] profile, complete with user and secret.

You’re now operating as bob, so let’s see what happens when we try a few different commands.

Checking Status of the Process

The bobStatusOnlyBucketProcess rule gave bob the ability to check the status of bucketProcess, so let’s give it a whirl. We’ll start by requesting the fine-grained status report:

fugue status bucketProcess

We see the following output:

AccountId:   fugue-1507311378131
FID:         bc2e3ca6-6662-45ff-a4e4-bebbfeadbc8d
LastMessage: SUCCESS
Status:      SUCCEEDED
Enforcement: ENABLED
Lock Status: DISABLED

Resources:
  S3_buckets:
  - acl:
      ACL: authenticated-read
    bucket:
      CreationDate: 1513555028
      Name:         fugue-docs-bucket-repo
    policy:
      Policy: '{"Version":"2012-10-17","Statement":[{"Sid":"fugue-docs-bucket-repo","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::xxxxxxxxxxxx:root"},"Action":"s3:*","Resource":"arn:aws:s3:::fugue-docs-bucket-repo/*"}]}'
    region: us-east-1
    tags:
      TagSet:
      - Key:   Application
        Value: Artifact repository
      - Key:   Fugue ID
        Value: bc2e3ca6-6662-45ff-a4e4-bebbfeadbc8d.de654c30-e805-5407-a75c-be0bc90dccb4
      - Key:   Name
        Value: bucketRepo

bob can also see the less verbose report by executing fugue status. If other processes are running, bob will only see the processes he has permission to see – in this case, bucketProcess.

Fugue Status Report for main-user/xxxxxxxxxxxx - Sun Dec 17 2017 7:45pm

State    Updated    Created    Account              FID                                   Alias          Flags    Last Message    Next Command
-------  ---------  ---------  -------------------  ------------------------------------  -------------  -------  --------------  --------------
Running  7:32pm     6:56pm     fugue-1507311378131  bc2e3ca6-6662-45ff-a4e4-bebbfeadbc8d  bucketProcess  -e       SUCCEEDED

Trying to Execute Prohibited Commands

Since RBAC access is implicitly denied, bob only has the permissions explicitly granted to him in the RBAC policy. We’ve confirmed that bob can execute the status command, the single action he’s permitted to take. What happens if he tries to execute a different command, like kill? Let’s try it out:

fugue kill -y bucketProcess

Sorry, bob! We get an error message, as expected:

[ fugue kill ] Killing process with Alias: bucketProcess

[ ERROR ] Due to an attached RBAC policy, command 'kill' is not allowed for user 'bob' on process [bc2e3ca6-6662-45ff-a4e4-bebbfeadbc8d].

bob can’t perform any other actions on bucketProcess, and if alice were to run another composition, bob wouldn’t be able to take any actions on the new process at all. The only way to grant bob more permissions is to modify the RBAC policy composition and execute fugue policy rbac-attach again – a task only alice is permitted to undertake.

When RBAC Permissions Overlap

You might be wondering what happens when rules seem to contradict or overlap with each other. For example, if we added bob to the secOps group, he’d have the following permissions:

  1. The secOpsRunDefaultAccount rules grant him access to the run command in the default account.
  2. The secOpsFullPermsBucketProcess rules grant him full permissions to bucketProcess.
  3. The bobStatusOnlyBucketProcess rule grants him access to the status command on bucketProcess.

It might seem like rules 2 and 3 contradict each other. One grants full permissions, and the other grants a single permission. Does one take precedence over the other?

Actually, there’s no contradiction here. The rules are additive, so bob has all of the privileges that the three rules grant. That’s because rules can only add permissions; they can’t remove permissions. Once a permission has been granted, it’s granted.

So instead of “Bob has full permissions” OR “Bob has this particular permission,” it’s “Bob has full permissions” AND “Bob has this particular permission.” (In this case, secOpsFullPermsBucketProcess grants bob full permissions to bucketProcess, including checking its status, so the bobStatusOnlyBucketProcess rule is redundant. It isn’t harmful to keep it in the policy, but it’s a good practice to remove unnecessary code.)

As you can see, rules 2 and 3 demonstrate when a process-level rule overlaps another process-level rule, but all rules are handled the same way. Whether they function at the process level, the account level, or a mixture of both, the rules are additive.

What happens when RBAC permissions appear to overlap.

What happens when RBAC permissions appear to overlap.

If you’d like to test this concept out yourself, follow these steps:

1. Edit line 10 of BucketRBACPolicy.lw so that it appears like this:

secOps: [alice, bob]

2. Switch back to alice:

fugue user set -p alice alice <secret>

3. Attach the updated RBAC policy composition to the Conductor:

fugue policy rbac-attach BucketRBACPolicy.lw

4. Switch back to bob:

fugue user set -p bob bob <secret>

You’ll notice that bob can still retrieve the status of bucketProcess, but as a member of secOps he can also take all other process actions on it, and he can create a new process in the default account.

Shutting It Down

It’s time to kill the process. When you’re ready, switch the active user from bob to root. Use the fugue user set command with the -p flag again:

fugue user set -p default-<AWS account>-<region> root <secret>

Now that root is the active user, kill the composition and use the -y flag to suppress the confirmation dialog:

fugue kill -y bucketProcess

You’ll see output like this:

[ fugue kill ] Killing process with Alias: bucketProcess

Requesting the Conductor to kill Running composition with Alias: bucketProcess...
[ Done ] The conductor is killing the process with Alias: bucketProcess

Finally, the last step is to wipe the RBAC policy attached to the Conductor. There are a few options:

  • If you have another policy composition you’d like to use, you can upload that with fugue policy rbac-attach.
  • If you’d rather “reset” the policy and remove the rules and users, you can upload a blank composition.
  • If you want to remove the policy but keep the users and secrets intact, you can detach the policy from the Conductor with fugue policy rbac-detach.

We recommend uploading a blank composition for a fresh start, but pick whatever suits your needs.

And that’s it! You’re all done. Here’s a recap of the awesome things you just did during this two-part walkthrough:

  • Wrote a composition declaring an S3 bucket with an IAM policy
  • Wrote a policy composition declaring rules that govern access to the RBAC metadata, the default Fugue account, and the S3 bucket process
  • Enabled two new users, alice and bob
  • Created a new process as alice
  • Checked its status as bob
  • Killed the process as root

As a result, you secured an S3 bucket with multiple levels of access control – IAM policy, process-level and account-level RBAC, and RBAC metadata. You also got a crash course in how RBAC rules interact with each other. Nice work!

Next Steps

If you want to review RBAC basics, see Adding Users (RBAC), How To Use RBAC, or RBAC Use Cases and Best Practices. To learn more about writing a policy composition, check out the Fugue.System.Policy library in the Standard Library Reference. If you missed our introductory RBAC walkthrough, visit Using the RBAC Feature. And as always, reach out to support@fugue.co with any questions.