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
- 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:
- podman login
- podman pull
- podman push (as needed)
- Be sure to test these commands within the RapidFort runner container or pod (as opposed to the host)
- Set up a RapidFort service account on the RapidFort runner
- Create a RapidFort service account and update the ~/.rapidfort/credentials file on the RapidFort runner OR
- Run rflogin <email> on the RapidFort runner
- 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
- 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
API Endpoints
Stub
- 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
-
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
-
The Content-Type must be specified as multipart/form-data.
-
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.
-
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.
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'
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'
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'
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"}'
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"}'
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}'