Installing the RapidFort API Runner

The RapidFort API runner provides endpoints to stub, harden, and scan container images.

Introduction

The RapidFort runner is a microservice that provides endpoints to stub, harden, and scan container images. Typically it is used in certain government or other restricted environments. Instead of having to install the RapidFort CLI tools and dependencies on your CI/CD pipeline runner and run rfstub and rfharden directly, you can give the RapidFort runner access to your container registries and call the RapidFort runner endpoints from your CI/CD pipeline runner to generate stub and hardened images there.

RapidFort Image Types

Before getting started, let’s review the different types of images that will be referenced:

  • The original image is the image from your container registry or your customer’s container registry.
  • The stub image is the original image built with additional dependencies needed for RapidFort to trace the runtime behavior and generate the runtime profile.
  • The hardened image is the optimized and secured image. By default, all files that were not detected as in use while the runtime behavior of the stub image was being traced will be removed (use it or lose it). However, RapidFort provides a variety of options for customizing what is kept in the hardened image. The hardened image does not contain any dependencies for tracing.

Runner Setup

  1. Set up a service account for each container registry that the RapidFort runner will need to interact with. Verify that the following commands can be run successfully within the RapidFort runner container or pod:
    1. podman login
    2. podman pull
    3. podman push (as needed)
    4. Be sure to test these commands within the RapidFort runner container or pod (as opposed to the host)
  2. Set up a RapidFort service account on the RapidFort runner
    1. Create a RapidFort service account and update the ~/.rapidfort/credentials file on the RapidFort runner OR
    2. Run rflogin <email> on the RapidFort runner
  3. Send a curl request with the appropriate payload to the RapidFort runner from your CI/CD pipeline


Registry, Repository, Tag

The RapidFort runner always expects the fully qualified image name. For example:

  • registry.example.com:8081/webapps/backend/db-access:v1.2.3
  • 012345678910.dkr.ecr.us-east-1.amazonaws.com/frontend:latest
  • docker.io/bitnami/redis:10-debian-10
To avoid issues with parsing, the registry, repository, and tag must be specified explicitly.
  • The registry is the registry server where the RapidFort runner will authenticate (i.e. podman login <registry>) before pulling or pushing images.
  • The repository is everything after the registry and before the tag (before the final “:”). Note that the repository may contain namespaces, e.g. webapps/backend/db-access.
  • The tag is after the repository.
  • The fully qualified image name is <registry>/<repository>:<tag>


Auth Configuration

By default, the RapidFort runner will look for registry credentials in the runtime auth file. For Podman this is in ${XDG_RUNTIME_DIR}/containers/auth.json e.g. /run/containers/auth.json
The caller can upload an Auth file by sending a multipart request.

{
  "auths": {
    "<registry_server>": {
      "auth": "<base64_username:password>" 
    },
    "<registry_server>": {     
      "auth": "<base64_username:password>"
    }
  }
}
 

Limitation

Currently, the API runner doesn't work when the same registry is used as source & destination and different repositories are used. It works when the registries are different. It works fine when both the registry and the repo are the same. The problem is that it's not retagging the image with destination when only the repository changes and it's re-using the source repo for the destination repo.. This will be addressed in a subsequent release.

​API Endpoints

Stub

/runner/api/v1/stub
Generate a stub image. The runner will pull the original image from the registry, generate a stub image, and push the stub image to the stub registry.
  • The runner must have permissions to pull images from the registry that contains the original image
  • The runner must have permissions to push images to the stub registry (this could be the same as the registry that contains the original image or a different registry)
 
 
METHOD PAYLOAD
      POST
{
“email” : <email>,
“registry” : <registry>,
“repository” : <repository>,
“tag” : <tag>,
“stub_registry” : <stub_registry>,
“stub_repository” : <stub_repository>,
“stub_tag” : <stub_tag>,
“workload_tag” : <workload_tag>,
“workload_tag_description” : <workload_tag_description>,
“cleanup”: : <cleanup>
}

 

Table 1: Stub API POST Payload

 

Parameter
Type
Description
email
str
the email account that the RapidFort runner should use for this job. this email must exist in the RapidFort credentials file on the RapidFort runner
registry
str
the registry where the original image should be pulled from
repository
str
the original image repository
tag
str
the original image tag
stub_registry
str
the registry where the stub image should be pushed to. this could be the same as the registry where the original image is pulled from
stub_repository
str
the stub repository
stub_tag
str
the stub tag
workload_tag
str
(optional, default none) workload tag
workload tags can be used to reuse runtime profile information when hardening images.
workload_tag_description
str
(optional, default none) workload tag description
cleanup
bool
(optional, default false) remove the original image and stub image from podman (podman rmi) after the RapidFort runner is finished

 Table 2: Stub API POST Parameter Details

 

Multipart Requests Auth Files

  • The Content-Type must be specified as multipart/form-data. 6 RapidFort Confidential
  • The Auth file must be available on the system (e.g. GitLab runner) from which the request is being sent.
  • The absolute path for the Auth file must be specified.
  • The Auth file must be specified in the request with the name docker_config_json, e.g.
  • docker_config_json="@/mypath/auth.json"
  • This parameter name will be made agnostic of the runtime type in a future release
  • The JSON payload must be sent as part of the request. The request type must be specified as "application/json". Please see the examples below.

Example 1: JSON Request

curl https://rapidfort.example.com/runner/api/v1/stub -X POST -d
'{"email":"admin@example.com","registry":"registry-external.example.c
om","repository":"agencies/defense-unicorns/podinfo","tag":"6.0.3","s
tub_registry":"registry-dev.example.com","stub_repository":"agencies/
defense-unicorns/podinfo","stub_tag":"6.0.3-rfstub"}'

Example 2: Multipart Request with Auth File

curl https://rapidfort.example.com/runner/api/v1/stub -X POST -H
"Content-Type: multipart/form-data" -F
docker_config_json="@/mypath/auth.json" -F
json_payload='{"email":"admin@example.com","registry":"registry-exter
nal.example.com","repository":"agencies/defense-unicorns/podinfo","ta
g":"6.0.3","stub_registry":"registry-dev.example.com","stub_repositor
y":"agencies/defense-unicorns/podinfo","stub_tag":"6.0.3-rfstub","ver
bose":true};type=application/json'

 

Harden

/runner/api/v1/harden
Generate a hardened image. The runner will generate a hardened image from the specified stub image and push the hardened image to the registry.
  • The stub image must have already been generated and tested (i.e. runtime profile information must be available or else hardening will fail)
  • The runner must have permission to pull the stub image from the registry
  • The stub image tag (not the original image tag) must be specified in the request
  • The runner must have permission to push the hardened image to the registry (this could be the same registry as the stub image or a different registry)
 

JSON Payload 

METHOD PAYLOAD
      POST
{
“email” : <email>,
“stub_registry” : <stub_registry>,
“stub_repository” : <stub_repository>,
“stub_tag” : <stub_tag>,
“hardened_registry” : <hardened_registry>,
“hardened_repository” : <hardened_repository>,
“hardened_tag” : <shardened_tag>,
“workload_tag” : <workload_tag>,
"preset" : <preset>, <workload_tag_description>,
"keep_data_files" : <keep_data_files>,
"keep_pkgs_coherent" : <keep_pkgs_coherent>,
"verbose" : <verbose>,
 “cleanup” : <cleanup>
}

Table 3: Harden API POST Payload

 
Parameter
Type
Description
email
str
the email account that the RapidFort runner should use for this job. this email must exist in the RapidFort credentials file on the RapidFort runner
stub_registry
str
the registry where the stub image should be pulled from
stub_repository
str
the stub image repository
stub_tag
str
the stub image tag
hardened_registry
str
he registry where the hardened image should be pushed to
hardened_repository
str
the hardened image repository
hardened_tag
str
the hardened image tag
workload_tag
str
(optional, default none) workload tag
workload tags can be used to reuse runtime profile information when hardening images.
preset
str
(optional, default "aggressive") hardening profile preset
must be one of ("aggressive", "standard", "light") for more information, please refer to the User Documentation
keep_data_files
bool
(optional, default false) keep data (non-executable) files
may be used in combination with a hardening profile preset or a custom hardening profile file for more information, please refer to the User Documentation
keep_pkgs_coherent
bool
(optional, default false) keep packages coherent
may be used in combination with a hardening profile preset or a custom hardening profile file for more information, please refer to the User Documentation
verbose
bool
(optional, default false) verbose mode
cleanup
bool
(optional, default false) remove the stub image and hardened image from Podman (podman rmi) after the RapidFort runner is finished

Table 4: Harden API POST Parameter Details

 

Multipart Requests Auth Files
  • The Content-Type must be specified as multipart/form-data.
The Auth file must be available on the system (e.g. GitLab runner) from which the
  • request is being sent.
  • The absolute path for the Auth file must be specified.
  • The Auth file must be specified in the request with the name docker_config_json, e.g.
  • docker_config_json="@/root/.docker/config.json"
  • This parameter name will be made agnostic of the runtime type in a future release
  • The JSON payload must be sent as part of the request. The request type must be specified as "application/json". Please see the examples below.
Custom Profile Files
To harden an image with a custom profile file, you will need to send a multipart request. The contents of the profile file will be saved to a temporary file on the RapidFort runner for use during the hardening process and will be cleaned up afterwards.
  • The Content-Type must be specified as multipart/form-data.
  • The profile file must be available on the system (e.g. GitLab runner) from which the
  • request is being sent.
  • The absolute path for the profile file must be specified.
  • The profile file must be specified in the request with the name profile_file, e.g.
    • profile_file="@/mypath/.rfignore"
  • The JSON payload must be sent as part of the request. The request type must be specified as "application/json". Please see the examples below.
Please note that if you do not need to specify a profile file, then you may send a multipart request that contains only the JSON payload.
Furthermore, you may also send non-multipart requests that contain only the JSON payload.
As of version 1.1.16, both a hardening preset and a custom hardening profile file may be specified together.
For more information on how each hardening option works, please refer to the User Documentation.
 
Example 1: Multipart request with a custom profile file
curl https://rapidfort.example.com/runner/api/v1/harden -X POST -H
"Content-Type: multipart/form-data" -F
profile_file="@/mypath/.rfignore" -F
json_payload='{"email":"admin@example.com","stub_registry":"registry-
dev.example.com","stub_repository":"agencies/defense-unicorns/podinfo
","stub_tag":"6.0.3-rfstub","hardened_registry":"registry-unapproved.
il2.gamewarden.io","hardened_repository":"agencies/defense-unicorns/p
odinfo","hardened_tag":"6.0.3-rfhardened","verbose":true};type=applic
ation/json'
Example 2: Multipart request with a hardening preset and custom profile file
curl https://rapidfort.example.com/runner/api/v1/harden -X POST -H
"Content-Type: multipart/form-data" -F
profile_file="@/mypath/.rfignore" -F
json_payload='{"email":"admin@example.com","stub_registry":"registry-
dev.example.com","stub_repository":"agencies/defense-unicorns/podinfo
","stub_tag":"6.0.3-rfstub","hardened_registry":"registry-dev.example
.com","hardened_repository":"agencies/defense-unicorns/podinfo","hard
ened_tag":"6.0.3-rfhardened","preset":"standard","verbose":true};type
=application/json'
Example 3: Multipart Request with a custom profile file and Auth file
curl https://rapidfort.example.com/runner/api/v1/harden -X POST -H
"Content-Type: multipart/form-data" -F
profile_file="@/mypath/.rfignore" -F
docker_config_json="@/mypath/auth.json" -F
json_payload='{"email":"admin@example.com","stub_registry":"registry-
unapproved.il2.gamewarden.io","stub_repository":"agencies/defense-uni
corns/podinfo","stub_tag":"6.0.3-rfstub","hardened_registry":"registr
y-dev.example.com","hardened_repository":"agencies/defense-unicorns/p
odinfo","hardened_tag":"6.0.3-rfhardened","verbose":true};type=applic
ation/json'

Example 4: Multipart Request without a custom profile file

curl https://registry.example.com/runner/api/v1/harden -X POST -H
"Content-Type: multipart/form-data" -F
json_payload='{"email":"admin@example.com","stub_registry":"registry-
dev.example.com","stub_repository":"agencies/defense-unicorns/podinfo
","stub_tag":"6.0.3-rfstub","hardened_registry":"registry-dev.example
.com","hardened_repository":"agencies/defense-unicorns/podinfo","hard
ened_tag":"6.0.3-rfhardened","verbose":true};type=application/json'
Example 5: JSON Request without a custom profile file
curl https://rapidfort.example.com/runner/api/v1/harden -X POST -d
'{"email":"admin@example.com","stub_registry":"registry-dev.example.c
om","stub_repository":"agencies/defense-unicorns/podinfo","stub_tag":
"6.0.3-rfstub","hardened_registry":"registry-dev.example.com","harden
ed_repository":"agencies/defense-unicorns/podinfo","hardened_tag":"6.
0.3-rfhardened"}'
Example 6: JSON Request without a custom profile file and with a hardening preset (standard)
curl https://rapidfort.example.com/runner/api/v1/harden -X POST -d
'{"email":"admin@example.com","stub_registry":"registry-dev.example.c
om","stub_repository":"agencies/defense-unicorns/podinfo","stub_tag":
"6.0.3-rfstub","hardened_registry":"registry-dev.example.com","harden
ed_repository":"agencies/defense-unicorns/podinfo","hardened_tag":"6.
0.3-rfhardened","preset":"standard"}'
Example 7: JSON request without a custom profile file and with a hardening preset (light) and keep_data_files hardening option
curl https://rapidfort.example.com/runner/api/v1/harden -X POST -d
'{"email":"admin@example.com","stub_registry":"registry-dev.example.c
om","stub_repository":"agencies/defense-unicorns/podinfo","stub_tag":
"6.0.3-rfstub","hardened_registry":"registry-dev.example.com","harden
ed_repository":"agencies/defense-unicorns/podinfo","hardened_tag":"6.
0.3-rfhardened","preset":"light","keep_data_files":true}'