Set up the IAM role and policies for Yarkon Server

Yarkon Server gets its permissions through IAM policies. It will never allow any end user more than the policy specify, and since the Yarkon Server and client applications both only use the AWS API to communicate with the AWS back-end, neither can ever perform an action not explicitly allowed by the administrator. The administrator has full control over the permissions granted, and the flexibility is similar to what AWS IAM affords.

How does it work

Yarkon Server has three different Security Models, controlling user access to the S3 buckets:

  • Shared security
  • Federated security
  • Integrated security

The Security Model is set using the Administration Page, Access Tab of the Yarkon Server application.

Security Model

The following table explains the differences between them:

Security Model Description Use Case
Shared Security All end users have the same S3 permissions. These permissions are defined by the security credentials provided to Yarkon, through an IAM user. This model is most applicable for smaller organizations where all users have the same access level. Another common use case is when setting up Yarkon on a departmental level, and all users are granted similar permissions.
Integrated Security Different users have different S3 permissions. You can define user access at the user, group or role level. This model is most applicable for larger organizations where users have specific permissions, based on their job requirements. Another common use case is when Yarkon is used to provide access to external users that should have limited access compared to internal users.
Federated Security Different users have different S3 permissions. You can define user access at the user, group or role level. This model is most applicable for larger organizations where users have specific permissions, based on their job requirements. A common use case is when Yarkon is used as a Private Hosting solution and you want to control a AWS account that is not the same as the one where the instance is running.

IAM Set up

As you can see in the above, there are few ways of setting up the server, depending on your use case and preferences. In the below, are specific guides for the different scenarios. You can definitely experiment with the settings and customize the following to best fit your own specific use case.

Create the Principal Policy

The recommended approach is to start with setting up an IAM policy. This policy can later be used with any of the security models supported by Yarkon Server, and should be the same for all. Follow these steps:

  1. Using the AWS Console, go to the IAM service.
  2. Create a new policy, name it something explicit, such as yarkon-console-policy.

The most generic policy - that is, one that would work for all security models - is:

{
    "Version": "2012-10-17",
    "Statement": [{
            "Sid": "AllowAllS3Actions",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::*"
        }, {
            "Sid": "AllowUIToDisplayIAMOptions",
            "Effect": "Allow",
            "Action": [
                "iam:List*",
                "iam:Get*"
            ],
            "Resource": "arn:aws:iam::<account-number>:*"
        }, {
            "Sid": "AllowTheRoleToGetPermissions",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::<account-number>:role/yarkons3-console-role"
        }, {
            "Sid": "AllowTheRoleToFederate",
            "Effect": "Allow",
            "Action": [
                "sts:GetFederationToken"
            ],
            "Resource": "arn:aws:sts::<account-number>:*"
        }, {
            "Sid": "AllowUsingSESForEmail",
            "Effect": "Allow",
            "Action": "ses:SendRawEmail",
            "Resource": "*"
        }
    ]
}

In all policies shown here, make sure to replace the <account-number> with your AWS account number. Your AWS account number is a 12 digit account ID. See this document from Amazon in case you do not have this ID handy.

Details (see the Sid attributes for reference):

AllowAllS3Actions - allows the Yarkon Server full access to S3. If you want to limit the usage of Yarkon in your organization to a predefined set of buckets, replace the statement with the below:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowServerToIterateBuckets",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Sid": "AllowServerToAccessSpecificBuckets",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance",
                "arn:aws:s3:::yarkons3-sales"
            ]
        },
        {
            "Sid": "OptionalAllowServerToAutomaticallyUpdateCORS",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketCORS",
                "s3:PutBucketCORS"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance",
                "arn:aws:s3:::yarkons3-sales"
            ]
        },
        {
            "Sid": "AllowUserActionsLimitedToSpecificBuckets",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::yarkons3-finance/*",
                "arn:aws:s3:::yarkons3-sales/*"
            ]
        }
    ]
}

AllowUIToDisplayIAMOptions - only required when using Federated or Integrated security models. The Yarkon Server does not need IAM access when set to use the Shared security model. This setting has no impact on the permissions granted to end users. If you only intend to use the Shared model, you can remove it.

AllowTheRoleToGetPermissions - only required when using the Integrated security model. You can remove it if using any of the other models. The role name specified, yarkons3-console-role assumes this is the name you'd be using for the IAM role required (see below). If you choose a different name, make sure to update here.

AllowTheRoleToFederate - only required when using the Federated security model. You can remove it if using any of the other models.

AllowUsingSESForEmail - only required if you intend to use Email integration, and would be using AWS SES as your mail server. If you do not intend to integrate Yarkon Server with an email server, or will be using a standard SMTP server, you can remove this section.

You can further restrict what any end user would be able to do when using the Yarkon web client application. To do so, update the statement AllowAllS3Actions (or AllowUserActionsLimitedToSpecificBuckets) to have more explicit set of permissions. For instance, if you want all users to have at most read-only access to a specific bucket, update the Action attribute in the policy to [ "s3:Get*", "s3:List*" ].

EC2 Instance with an IAM Role

When using an EC2 instance, if you can run it with a IAM role, it is the simplest and most secure way - because no API credentials are required, hence there is no risk these credentials would be compromised.

If you are using an EC2 instance, but cannot associate it with the Yarkon IAM role, follow the instructions below for the setup for Non EC2 Server.

The next and final step is to create the IAM role:

  1. Using the AWS Console, go to the IAM service.
  2. Create a new role, name it something explicit, such as yarkon-console-role.
  3. For the Permissions, attach the policy you created to this role.
  4. Edit the Trust relationship for the role using the below policy (the Sid named AllowAssumeRole is what was added):
{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": {
            "Service": "ec2.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
    },
    {
        "Sid": "AllowAssumeRole",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::<account-number>:root"
        },
        "Action": "sts:AssumeRole"
    }]
}

Launch the EC2 instance with this IAM role. For more on IAM roles, read this document from Amazon.

Non EC2 server

When using a unix server (or an EC2 instance without an IAM role), credentials are provided to the application using the environment.

Important: The AWS access keys you are about to provision in the next step are used by the Yarkon Admin Console only. They are never shared with the end users. End users only get short lived temporary access credentials that are based on the permissions granted to these access keys. You will only need to use these access credentials once, during the set up of Yarkon, as described later on in this guide.

The first step is to get these credentials.

  1. Using the AWS Console, go to the IAM service.
  2. Create a new user, name it something explicit, such as yarkon-console-user.
  3. Make sure to enable Programmatic access access for this user by checking the box under AWS access type.
  4. For the Permissions, attach the policy you created to this user.
  5. When the user is created, you will be given the API credentials associated with it. Keep these for the next step.

Next, you want to present the credentials to the running application. There are two ways to accomplish that, choose whichever is simpler for your use case.

  1. Use a config file. The file should be placed in the folder ~/.aws/credentials and include the API credentials created. If you are not familiar with AWS credential files, follow this document from Amazon.
  2. Provide the environment variables when launching the application. Review this document from Amazon.

Docker Container

When using a docker container, if possible, you want to set the IAM role at the container level. If this is the case, then it would behave exactly like the aforementioned EC2 instance with an IAM role.

If you cannot set an IAM role for your docker container, credentials are provided to the container in a similar manner to the aforementioned Non EC2 Server, so acquire the API credentials in the same way. Once you have them, pass them to the container just like you would any other env variables.

The following example shows how to accomplish this task using a standard docker-compose file:

version: "3"

services:
  server:
    image: "yarkon/server:latest"  # Use the correct tag here
    ports:
      # Map the port of the host to the one used by Yarkon
      - "80:8000"
    environment:
      # When running in AWS, the preferred way to provide AWS API keys to the
      # container is through using an IAM machine role. If this cannot be done,
      # or when running it outside of AWS, you can pass credentials here:
      AWS_ACCESS_KEY_ID: "EXAMPLERFP4S3EXAMPLE"
      AWS_SECRET_ACCESS_KEY: "examplexcRA2gvPBPKAmt95yWIwz/vJIJexample"
      AWS_REGION: "us-east-1"

      # The provider name defaults to AWS, but you can change it to something
      # your users might find more recognizable. In the client, it is displayed
      # above the buckets and in the About form.
      PROVIDER_NAME: "My Company"

    volumes:
      - dbdata:/var/app/current/database
      - license:/var/app/current/.lic
      - yarkon:/var/app/current/public/yarkon
      - /var/log:/var/app/current/log # Map the /var/log folder on the host to the log folder
volumes:
  dbdata:
  license:
  yarkon: