avatarTeri Radichel

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3786

Abstract

arison operators, and bitwise operators on this type too.</p><p id="c4da">It’s important to note that there is another type, called <code>bytes</code> which is different from the above in that it is a dynamically sized array, and not a value type but a reference type. It is basically shorthand for <code>byte[]</code>.</p><p id="ad39">When you can limit the length of your data to a predefined amount of bytes, it is always good practice to use some of <code>bytes1</code> to <code>bytes32</code> because it is much cheaper.</p><h2 id="0118">Enums</h2><p id="aea7"><b>Enums</b> in Solidity are a way to create user-defined types. Enums are explicitly convertible to integer types, but not implicitly. Enum values are numbered in the order they are defined, starting from 0.</p><p id="ed00">Enums are not part of the ABI (Application Binary Interface — more on this in a later lesson, but it’s basically how you encode Solidity code for the Ethereum Virtual Machine, and how you get data back). This means that if your function returns an <code>enum</code> for example, it will be automatically converted to a <code>uint8</code> behind the scenes. The integer returned is just large enough to hold all enum values. With more values, the size gets increased too (<code>uint16</code> and up).</p><p id="cdb6">The below code, taken from the <a href="https://docs.soliditylang.org/en/v0.4.24/index.html">Solidity docs</a>, defines an enum with four possible values, creates a variable of that enum named <code>choice</code> and a constant called <code>defaultChoice</code>that will hold a default value.</p><div id="cf29"><pre><span class="hljs-keyword">enum</span> <span class="hljs-title class_">ActionChoices</span> { GoLeft, GoRight, GoStraight, SitStill } ActionChoices choice; ActionChoices <span class="hljs-type">constant</span> <span class="hljs-variable">defaultChoice</span> <span class="hljs-operator">=</span> ActionChoices.GoStraight;</pre></div><p id="66a9">Now we can define some functions to interact with our <code>enum</code>.</p><div id="c0bb"><pre><span class="hljs-title function_"><span class="hljs-keyword">function</span> <span class="hljs-title">setGoStraight</span></span>() <span class="hljs-keyword">public</span> { choice = ActionChoices.GoStraight; }

<span class="hljs-title function_"><span class="hljs-keyword">function</span> <span class="hljs-title">setChoice</span></span>(ActionChoices <span class="hljs-keyword">new</span><span class="hljs-type">Choice</span>) <span class="hljs-keyword">public</span> { choice = <span class="hljs-keyword">new</span><span class="hljs-type">Choice</span>; }</pre></div><p id="6bc2">The first one simply sets the <code>choice</code> to <code>GoStraight</code> while the second one sets it to the choice that the caller passes into the function. As we can see after deployment, the <code>setChoice</code> function expects a <code>uint8</code> value, which corresponds to the <code>enum</code> value declared at that number.</p><figure id="e997"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*1pKNPVy4UUBCSLi2-SIckg.png"><figcaption>Testing enums in Remix</figcaption></figure><p id="7917">If we want to get the value of <code>choice</code> and <code>defaultChoice</code>, we can define the following functions:</p><div id="1f02"><pre><span class="hljs-keyword">function</span> <span class="hljs-title">getChoice</span>() public view returns (ActionChoices) { <span class="hljs-keyword">return</span> <span class="hljs-type">choice</span>; }</pre></div><div id="43e7"><pre><span class="hljs-function">function <span class="hljs-title">getDefaultChoice</span>() <span class="hljs-keyword">public</span> pure <span class="hljs-title">returns</span> (<span class="hljs-params"><span class=

Options

"hljs-built_in">uint</span></span>)</span> { <span class="hljs-keyword">return</span> <span class="hljs-built_in">uint</span>(defaultChoice); }</pre></div><p id="c2f2">As we can see if we try this out in Remix, the first function returns a <code>uint8</code> while the second returns a <code>uint256</code>.</p><figure id="e514"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*jmaOFb9GhXz7FWC4ONMa_A.png"><figcaption>Testing enums in Remix</figcaption></figure><h2 id="3c7c">Fixed point numbers</h2><p id="2ecc"><b>Fixed point numbers </b>represent fractional numbers by storing a fixed number of digits of their fractional part. No matter how large or small the fractional part is, it will always use the same number of bits.</p><p id="cdcd" type="7">Fixed point numbers are not fully supported by Solidity yet. They can be declared, but cannot be assigned to or from.</p><p id="f872">We can differentiate between signed fixed point numbers, declared with the <code>fixed</code> keyword, and unsigned fixed point numbers, declared with the <code>ufixed</code> keyword.</p><p id="3c1c">It can also be declared as <code>fixedMxN</code> or <code>ufixedMxN</code> where <code>M</code> represents the number of bits the type takes, and <code>N</code> represents the number of decimal points. <code>M</code> has to be divisible by 8 and a number between 8 and 256. <code>N</code> has to be a number between 0 and 80.</p><p id="96e1">They function with the following operators:</p><ul><li>Comparisons: <code><=</code>, <code><</code>, <code>==</code>, <code>!=</code>, <code>>=</code>, <code>></code> (evaluate to <code>bool</code>)</li><li>Arithmetic operators: <code>+</code>, <code>-</code>, unary <code>-</code>, unary <code>+</code>, <code>*</code>, <code>/</code>, <code>%</code> (remainder)</li></ul><h2 id="09b7">Conclusion</h2><p id="bd3a">In this lesson, we looked at what value types are available in Solidity and how each one works.</p><p id="28de">Thank you for staying with us till the end. If you enjoyed reading this piece please keep in touch and follow Solidify to keep up with our lessons on Solidity. In the upcoming articles, we will deep dive into the intricacies of the language, progressing from beginner to advanced level.</p><p id="067c">If you are new to Solidity, check out the previous lessons about setting up a local development environment and writing your first smart contract.</p><div id="6b76" class="link-block"> <a href="https://readmedium.com/how-to-setup-your-local-solidity-development-environment-c4c8195810f3"> <div> <div> <h2>How to Setup Your Local Solidity Development Environment</h2> <div><h3>Get started with smart contract development</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*HHko-o9m1sVngmTeRVYgKA.jpeg)"></div> </div> </div> </a> </div><div id="3ad1" class="link-block"> <a href="https://readmedium.com/lesson-1-your-first-solidity-smart-contract-1ba7e641f9a3"> <div> <div> <h2>Lesson 1: Your First Solidity Smart Contract</h2> <div><h3>In the previous lesson, we looked at how to set up your local Solidity development environment. Here we will continue…</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*7r7HSYkbn73NrmR_skvh5w.jpeg)"></div> </div> </div> </a> </div></article></body>

Okta SAML Integration with AWS IAM Step 3: Creating SAML Roles

ACM.174 Determining permissions for an AWS Billing Administrator Role

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

⚙️ Check out my series on Automating Cybersecurity Metrics. The Code.

🔒 Related Stories: Cloud Governance | IAM | AWS Security | Okta

💻 Free Content on Jobs in Cybersecurity | ✉️ Sign up for the Email List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the last post, we set up an Identity Provider in AWS for Okta federation.

In this post we are going to add a role for federation with Okta.

Create a Billing Administrator Role

The first role we are going to test is our Billing Administrator role. The Billing administrator role will be able to add new accounts, but only add them to the DenyAll SCP to implement the segregation of duties described in this post:

We’ll follow Step 2 of these instructions in the Okta documentation:

Obtain the ARN for the AWS IAM Identity Provider

The first thing we need is the ARN for the AWS IAM Identity Provider (IdP) created in the last post. You can get this from the AWS IAM console or you can find it in the Outputs of the IdP CloudFormation stack we deployed.

We’re going to use that ARN below where it says to copy and paste the ARN into the example trust policy.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "<COPY & PASTE SAML ARN VALUE HERE>"
      },
      "Action": "sts:AssumeRoleWithSAML",
      "Condition": {
        "StringEquals": {
          "SAML:aud": "https://signin.aws.amazon.com/saml"
        }
      }
    }
  ]
}

We’re not going to copy and paste, however. We’re going to use the approach we’ve used throughout this series and reference the CloudFormation output above to populate the ARN in the CloudFormation template we use to deploy our new role. If you’re not familiar with that concept you might want to read this series from the start.

I wrote about the possibility of using MFA with Okta in a prior post, but for starters we’re going to start with the above. We’ll revisit adding MFA to the above trust policy later.

Create the Billing Administrator Role

What permissions do we need to give our Billing Administrator? That depends on exactly what actions you need this person to do in your company.

One action we know we want to give our billing administrator is the ability to create accounts, but only in the DenyAll Organizational unit we created here:

To determine the service and action we need to add to the IAM policy, navigate to the list of AWS IAM actions.

Click on AWS Organizations. We can see that the service prefix we need to use is “organizations” at the top of the page. I feel like this could visually more obvious, but just know that the service prefix is at the top of each service. page.

Scroll down to see the list of actions and take a look at CreateAccount. The last column shown below are Condition Keys. Those conditions are based on tags and a new account won’t have a tag nor do we want to require one so this doesn’t seem like what we want. We need to be able to only allow creation of the account in a specific OU.

How can we ensure that the account is only created with the DenyAll OU?

Well, fist of all we’ve denied permissions via an SCP to add accounts to the root OU so that should be blocked. We can test that when we add a new account — in theory that should be OK. But we need to test it.

To ensure that the billing administrator cannot add an account to any OU except the DenyAll OU, we can add a statement that denies all actions except on the DenyALL OU.

But here’s where things get tricky. When I look at AWS CloudFormation I see that I can assign a parent ID for a new account. That parent ID can be the OU where you want the account to end up.

When I look at the AWS CLI I see no such option:

When I look at the AWS Organizations permissions, I don’t see a permission specific to assigning an OU to a new AWS account. I only see the option to move an account to an OU.

My concern is that when creating an account via CloudFormation the account is created in the Root OU and then moved to the DenyAll OU. If that is the case, and all accounts must first be created in the Root OU, we’re going to need to change our SCP that denies adding accounts to the Root OU. Instead, we can enforce that any accounts in the DenyOU are assigned the DenyAll policy directly except the management account.

In that case, we can deny all actions on all OUs except Root and DenyALL.

We are adding this policy in the AWS Organizations management account so this is the only place where the billing administrator can perform these actions — and some actions can only be performed in the management account.

I wish AWS would provide a simple and concrete list of all the actions that can only be performed in the management account. Also it would be nice to indicate that in the AWS IAM documentation:

The list needs to include other related actions that cannot be delegated and can only be performed in the management account for other services like the billing functions I’ll write about next.

Other functions to grant a Billing Administrator

There are may other billing-related functions you may want to assign to your billing administrator. I’m listing some of them below and what I am going to assign to this policy. What you assign for your organization may vary. Also note that I do not see a way to delegate billing administration to a separate account at the time of this writing so it appears these actions must be taken in the management account for an organization.

In this midst of writing this, AWS is about to make changes to the IAM billing options. Instead of having a separate prefix for the console and programmatic actions, some actions are being combined under a single prefix. In addition, some prefixes will be divided up into more granular sets of permissions to be able to create more granular billing controls.

Essentially, we want to not assign the aws-portal permissions or the two purchase-order permission listed in the following blurb. We will want to take a look at the new service prefixes below, which unfortunately do not all have “cost” or “billing” in the name.

When you look up some of these new and altered services, AWS has added [permission only] under the name of the action. I have no idea what that means.

Although granular controls are nice, I find this change to be a bit complicated. There are way so many service prefixes for billing now. It may have been better to have less prefixes and more actions within each prefix. Competent IAM administrators would know how to create roles with only a subset of actions for a prefix in a policy, such as I have been doing throughout this series. AWS could provide appropriate management roles for those who want someone to create the policies for them. At a minimum, it would have been nice if all the prefixes had “billing” in the name so they all show up in the same place in the list. #awswishlist

Action: Budgets:*

Effect: Allow

I always set up a budget immediately in a new account. We can do that in a later post but it’s pretty simple if you take a look at the directions.

Account Management (account) — allow

All of the AWS Account Management services. Note that this includes enabling and disabling regions for an account. The Service Control Policy we created should override this. I feel like that is an access control that should belong to the governance team but we’ll leave it here for now.

Application Cost Profiler Service (application-cost-profiler) — deny

I will enable this service if and when needed.

Billing Conductor (billingconductor) — deny

I don’t have a use for this service at this time.

Cost Management Console (aws-portal) — N/A

The announcent was a bit confusing in terms of what was actually happening with the aws-portal prefix. However, AWS added an error message in my account recently while trying to use some of these actions:

So they definitely are being deprecated. The problem is, it’s not entirely clear which new actions replace which old actions. See future blog posts for more information.

Cost and Usage Report (cur) — allow

The billing administrator can manage cost and usage reports.

Cost Explorer Service (ce) — allow

The billing administrator can query costs.

Free tier (freetier)— allow

The billing administrator can manage the free tier alert preference.

Invoicing (invoicing) — deny

My billing administrator will not change the billing invoice delivery preferences.

Payments (payments)— deny

Root or OrgRoot will manage payment methods. (Note, I changed this in an upcoming post for accounts we are trying to close.)

Price List Service (pricing) — allow

The billing administrators can query the cost of AWS service programmatically.

Purchase Orders (purchase-orders)— deny

I don’t pay with purchase orders. You can enable this service if you do.

AWS tax (tax)— deny

The billing administrator cannot change the organization’s tax settings.

Code to deploy our Billing Administrator role

I’m going to add a new folder called OktaRole under my IAM folder in my code. I’m going to copy my existing code over to the OktaRole folder so I can reuse as much as possible, but alter it to work with Okta.

I may be breaking the DRY Principle a bit as we go but I want to be able to support either IAM roles or Okta roles and I don’t want to break what I already created for IAM roles.

Once again I need:

  • A functions script to deploy Okta roles.
  • CloudFormation templates for my new okta roles.
  • A deploy script.
  • Test scripts.

Functions Code

IAM/OktaRole/role_functions.sh

I modified deploy_group_role in role_functions.sh to replace every instance of group with okta. I updated the parameters to pass in a role name instead of a group name. I removed what is not extraneous group code since we’re not using AWS groups for this.

I also added a function to deploy Okta roles using the OrgRoot profile. I’ve been using simplified approach rather than passing in a profile override lately.

I removed these functions:

  • deploy_aws_service_role()
  • deploy_lambda_role()
  • deploy_batch_job_role()
  • deploy_ec2_instance_profile()

The deploy_role_policy function can work as is.

Role and Policy CloudFormation templates

Over in my /cfn directory I am going modify GroupRole.yaml to become OktaRole.yaml.

I need to change the parameters to send in the RoleName instead of the Group parameters.

I need to modify the AssumeRolePolicyDocument (called a Trust Policy in the AWS Console). I changed the Action from sts:AssumeRole to sts:AssumeRoleWithSAML.

As mentioned above I’m going to get the IdP value from my IdentityProvider CloudFormation stack:

I removed the MFA condition (for now) and added the SAML condition.

In the outputs, I replaced Group everywhere with Okta:

The full role CloudFormation template:

I removed the other roles from the cfn directory.

Role Policy

Next, I removed all the policies from the cfn/policy directory except the governance policy.

I changed every place it says “Group” to “Okta”. I change every place it says “Governance” to “Billing”.

I modified the actions and as noted above there may be some issues with the CreateAccount actions. This is what we have right now:

  • The policy below allows the billing administrator role to create an account.
  • The root SCP denies creating accounts at the root.
  • The policy below prevents the billing administrator from doing anything with the any OU except the DenyAll OU.

Once I can login with Okta using this role, we’ll verify this works as desired and troubleshoot as needed.

I’m also allowing the services mentioned above:

As per usual we are going to allow Billing Administrators to modify their own stacks:

This may pose another problem when we want to allow the governance user to move an account into a different OU. The stack takes a ParentID to create:

Then the stack needs to be updated to move the account into a new OU.

That means both the Governance team and the Billing team need access to update this CloudFormation stack per our design:

Let’s give our Organizational Account stacks a different prefix — Organization. The resource is going to be Account. So the naming convention for our stacks will be: Organization-Account-[AccountName]

So we’ll also let our billing administrators modify stacks that start with “Organization-Account”. We could further restrict the billing administrators to only create or delete stacks but not update them but our other permissions should limit the actions appropriately.

Here’s the whole policy:

Deployment Script

Next, I created the deploy_root_roles.sh script. It’s pretty simple:

Note that the role template will add the “Okta” prefix to all Okta roles so we don’t need to add that in the name above.

Shared Functions Update

I also had to add the OrgRoot user to my list of profiles that can use IAM capabilities in my deploy_stack function in the shared functions file: Functions/shared_functions.sh:

Test the deployment

Deploy the role and policy by running the following script from the OktaRole folder.

./deploy_root_policies.sh

Make sure you have created the OrgRoot profile discussed in prior posts starting here:

Confirm they are added to the AWS management account. Take note of the role ARN as that will be referenced in the next post, where we grant Okta users permission to assume the role.

Follow for updates.

Teri Radichel | © 2nd Sight Lab 2023

About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
⭐️ Author: Cybersecurity Books
⭐️ Presentations: Presentations by Teri Radichel
⭐️ Recognition: SANS Award, AWS Security Hero, IANS Faculty
⭐️ Certifications: SANS ~ GSE 240
⭐️ Education: BA Business, Master of Software Engineering, Master of Infosec
⭐️ Company: Penetration Tests, Assessments, Phone Consulting ~ 2nd Sight Lab
Need Help With Cybersecurity, Cloud, or Application Security?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🔒 Request a penetration test or security assessment
🔒 Schedule a consulting call
🔒 Cybersecurity Speaker for Presentation
Follow for more stories like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
❤️ Sign Up my Medium Email List
❤️ Twitter: @teriradichel
❤️ LinkedIn: https://www.linkedin.com/in/teriradichel
❤️ Mastodon: @teriradichel@infosec.exchange
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
AWS
Okta
Saml
Role
Policy
Recommended from ReadMedium