How Outpost Works
Outpost (also called InHost) runs the Relyance scanner in your own AWS account. The scanner reads and classifies data in your account. Relyance gets scan results, not your data.
You deploy Outpost with public, versioned code that you can read before you run it:
| What | Public reference | Version |
|---|---|---|
| Terraform module for the AWS resources | Relyance-Ext/sierra/aws (source) |
0.7.0 |
| Kubernetes manifests for the cluster components | https://assets.relyance.ai/inhost/k8s/v1.1.1/ |
1.1.1 |
| Terraform provider for connections | Relyance/relyance |
1.1.0 |
At a glance
- Apply the Terraform module in your AWS account. It creates two buckets, a KMS key and two IAM roles. It can also create the EKS cluster, or use one that you have.
- Send the module output to Relyance. Relyance sets up its side and sends you a small kustomize folder with the values for your deployment.
- Apply the manifests to the cluster with
kubectl. - Add connections to your data sources, in the Relyance web application or with the Terraform provider.
Relyance never gets access to your cluster, console or network. You run every step with your own tools and credentials. For the full commands, refer to Deployment plan.
Design principles
| Principle | What it means |
|---|---|
| Data stays in your account | The scanner reads and classifies data in your AWS account. Relyance gets scan results, not your data. |
| Credentials can stay with you | With the In Host BYOK runtime mode, the credentials for a data source stay in a secret in your account. Relyance stores only the location of the secret. |
| The cluster starts all connections | The Outpost cluster connects to Relyance. Relyance does not open connections to the cluster. |
| Limited, read-only access | Relyance has one read-only IAM role in your account. It can read only the scan results. |
| No telemetry | The Outpost manifests include no monitoring, log or telemetry agent. |
| You operate it | You deploy and operate Outpost. Relyance has no access to the cluster. |
Architecture
Outpost has two parts: the components in your AWS account, and the Relyance platform.
| Component | Where it runs | What it does |
|---|---|---|
| Scanner workers | Kubernetes cluster, your AWS account | Connect to the data sources, read sample data, classify it, and write the results. |
| Autoscaler | Kubernetes cluster, your AWS account | Starts scanner workers when scan commands wait. KEDA and a small scaler service do this. |
| Findings bucket | Your AWS account | Keeps the scan results. Relyance copies the results from this bucket. |
| Work bucket | Your AWS account | Keeps temporary data during a scan. Relyance cannot read it. |
| Secret store | Your AWS account | Keeps the credentials for the data sources, for In Host BYOK connections. |
| KMS key | Your AWS account | Encrypts the findings bucket and the work bucket. |
| Container registry | Relyance infrastructure | Supplies the scanner images. |
| Command queue | Relyance infrastructure | Holds scan commands until the cluster pulls them. |
| Control plane API | Relyance infrastructure | Supplies the connection settings and receives scan status. |
| Results copy and web application | Relyance infrastructure | Copies the scan results and shows them in the Relyance web application. |
How a scan works
The numbers match the arrows in the diagram.
- The cluster pulls the scanner images from the Relyance container registry.
- Relyance puts a scan command in the command queue. The autoscaler sees the waiting command and starts scanner workers. A scanner worker pulls the command.
- The scanner gets the connection settings from the control plane API. During the scan, it reports progress and completion to the same API. These reports contain status and counts, not your data.
- The scanner reads the credentials for the data source from the secret store.
- The scanner connects to the data source and reads sample data. The sample data stays in your account.
- The scanner keeps temporary scan data in the work bucket.
- The scanner classifies the sample data in the cluster and writes the results to the findings bucket.
- Relyance copies the results from the findings bucket with a read-only identity. The results show in the Relyance web application.
Deployment plan
Before you start
| You need | Details |
|---|---|
| An AWS account for Outpost | Use a dedicated account if you can. The scanner can read data sources in this account and in the accounts that you allow. |
| A cluster, or permission to create one | The module can create an EKS cluster in a new VPC. To use your own cluster, it must be EKS with Auto Mode and the EKS Pod Identity Agent add-on. |
| Terraform 1.9 or later | For the module. The Terraform provider for connections needs Terraform 1.11 or later. |
| AWS CLI | The module uses aws eks get-token to reach the cluster. |
| kubectl | Relyance tests the manifests with kubectl 1.33. |
| A Relyance tenant with Outpost turned on | Contact your Relyance team. |
Step 1: Create the AWS resources
Add the module to a Terraform configuration and apply it with your own AWS credentials.
To use an existing EKS cluster:
module "outpost" {
source = "Relyance-Ext/sierra/aws"
version = "0.7.0"
create_vpc_and_eks = false
existing_eks_cluster_name = "my-cluster"
# The AWS accounts whose IAM roles the scanner can assume to read data sources.
# Set this, or set assume_all_roles = true.
assumable_account_ids = ["111122223333"]
# The manifests deploy into the "inhost" namespace.
additional_service_account_namespaces = ["inhost"]
# Optional: secrets for In Host BYOK connections.
byok_secret_arn_patterns = [
"arn:aws:secretsmanager:us-west-2:111122223333:secret:relyance/inhost/*",
]
}
provider "aws" {
region = "us-west-2"
default_tags {
tags = module.outpost.default_tags
}
}
output "outpost" {
description = "Send this output to Relyance"
value = module.outpost
}To create a new EKS cluster, replace the cluster settings with the network ranges for the new VPC:
create_vpc_and_eks = true
vpc_cidr = "172.30.0.0/16"
service_cidr = "10.100.0.0/16"
nat_subnet_cidr = "172.30.255.0/24"
subnet_cidrs = {
usw2-az1 = "172.30.0.0/20"
usw2-az2 = "172.30.16.0/20"
usw2-az3 = "172.30.32.0/20"
usw2-az4 = "172.30.48.0/20"
}
# Empty means the cluster API endpoint is private only.
eks_public_access_cidrs = []Set one subnet for each availability zone ID in the region. Then run:
terraform init
terraform apply
terraform output -json outpostFor all inputs, refer to the module documentation.
What the module creates
| Resource | Name | Purpose |
|---|---|---|
| S3 bucket | relyance-findings-<account-id> |
Scan results. Versioning on, public access blocked, encrypted with the KMS key. |
| S3 bucket | relyance-work-<account-id> |
Temporary scan data. Same settings. |
| KMS key | alias/Relyance_Sierra |
Encrypts both buckets. Key rotation is on. When the module creates the cluster, it also encrypts the Kubernetes secrets. |
| IAM role | Relyance_Sierra |
The scanner role. The scanner pods get it through EKS Pod Identity. It can use both buckets, assume roles in the accounts that you allow, and read the secrets that match byok_secret_arn_patterns. |
| IAM role | Relyance_Sierra_Reader |
The Relyance read-only role. Only a Relyance IAM principal with an external ID that the module generates can assume it. It can list and read the findings bucket and decrypt with the key. It has no other permissions. |
| EKS Pod Identity association | relyance service account |
Connects the scanner pods to Relyance_Sierra. |
| VPC and EKS cluster | Relyance_Sierra |
Only when create_vpc_and_eks = true. Private subnets, two NAT gateways, EKS Auto Mode, a private API endpoint by default, and all control plane logs on. |
The module creates its own KMS key. It does not accept an existing key.
Step 2: Send the output to Relyance
Send the outpost output to your Relyance team. It contains no secrets. Relyance uses these values:
| Output | What Relyance does with it |
|---|---|
aws_account_id |
Records the account of your deployment. Relyance accepts secret ARNs only from this account. |
reader_external_id |
Assumes Relyance_Sierra_Reader to copy the scan results. |
oidc_issuer |
Lets the cluster sign in to the Relyance command queue and API with short-lived credentials, with no keys. |
Relyance then sends you a kustomize folder for your deployment. It points at the published manifests, and it adds your values: the Relyance project of your tenant, your bucket names, your region, and the identity settings. It contains no secrets.
Step 3: Install the cluster components
The manifests are plain YAML files on a public URL. The version is in the path, and each version never changes after it is published.
Install KEDA. Skip this step if KEDA is already in the cluster.
kubectl apply --server-side \ -f https://assets.relyance.ai/inhost/k8s/v1.1.1/keda-aws-prod-v1.1.1.yamlCreate the namespace.
kubectl create namespace inhostApply the folder from Relyance.
kubectl apply -k ./relyance-outpost
The kustomization.yaml in the folder starts like this:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://assets.relyance.ai/inhost/k8s/v1.1.1/services-aws-prod-v1.1.1.yaml
patches:
- path: patch-tenant-values.yaml
target:
version: v1
kind: ConfigMap
name: common-env
# ...To read the manifests before you apply them, download them and check them against the published checksums:
curl -fsSLO https://assets.relyance.ai/inhost/k8s/v1.1.1/services-aws-prod-v1.1.1.yaml
curl -fsSL https://assets.relyance.ai/inhost/k8s/v1.1.1/SHA256SUMS-v1.1.1.txt \
| shasum -a 256 -c --ignore-missingWhat the manifests install
| Kind | Name | Purpose |
|---|---|---|
| ScaledJob | gai-sampler, gai-analyzer, gai-sampler-worker, gai-analyzer-worker |
The scanner workers. KEDA starts them only when scan commands wait. |
| Deployment | inhost-scaler |
Tells KEDA how many scan commands wait. |
| StatefulSet | gai-redis-master |
Coordinates the workers of one scan. It runs in the cluster. |
| ServiceAccount | relyance, inhost-scaler |
The identities of the pods. |
| NodePool and StorageClass | inhost-jobs, inhost-gp3 |
Nodes and disks for scan jobs. These two are cluster-scoped. |
| ConfigMap, Service, PodDisruptionBudget | Settings and internal connections. |
The services file contains no Role, ClusterRole or CRD, and no monitoring, log or telemetry agent. The KEDA file installs the standard KEDA components, with their own CRDs and cluster roles. The pods run as non-root with all Linux capabilities dropped, and meet the Kubernetes Restricted Pod Security Standard.
Step 4: Add connections
A connection tells the scanner how to reach one data source. Set its runtime mode to run the scan in Outpost:
| Runtime mode | Where the scan runs | Where the credentials are |
|---|---|---|
| In Host BYOK | Outpost | In a secret in your account. Relyance stores only the secret ARN. |
| In Host | Outpost | Relyance stores them in its secret store. |
New connections start as Relyance-hosted. Set the runtime mode on each Outpost connection. Use In Host BYOK to keep the credentials in your account.
In the web application, follow Store Outpost Credentials in a Customer-Managed Secret.
With Terraform, use the Relyance provider. The provider signs in as a Relyance OAuth client with the Integration Configuration Management role. This example keeps the Jira credentials in AWS Secrets Manager. Only the secret ARN goes to Relyance:
terraform {
required_providers {
relyance = {
source = "Relyance/relyance"
version = "~> 1.1"
}
}
}
# Set RELYANCE_CLIENT_ID and RELYANCE_CLIENT_SECRET in the environment.
provider "relyance" {}
resource "aws_secretsmanager_secret" "jira" {
name = "relyance/inhost/jira"
}
resource "aws_secretsmanager_secret_version" "jira" {
secret_id = aws_secretsmanager_secret.jira.id
secret_string = jsonencode({
ORG_ID = "REPLACE_ME"
API_KEY = "REPLACE_ME"
})
lifecycle {
ignore_changes = [secret_string]
}
}
resource "relyance_integration_connection" "jira" {
vendor = "atlassian_jira"
name = "Jira (Outpost)"
runtime_mode = "IN_HOST_BYOK"
auth = {
method = "api-key"
params = {
data_storage_location = "us"
}
}
secret_ref = aws_secretsmanager_secret.jira.arn
scans = {
"vendor-discovery" = { enabled = true }
}
depends_on = [aws_secretsmanager_secret_version.jira]
}Put the real credential values in the secret outside Terraform, so that they are not in the Terraform state. The secret ARN must match byok_secret_arn_patterns in the module. For each vendor's fields and methods, refer to the provider documentation.
Authentication methods that need a browser sign-in (OAuth) go through Relyance, so Relyance gets those tokens. These methods cannot use a secret ARN. For the details, refer to Authentication methods that cannot use AWS Secrets Manager.
Step 5: Check the deployment
Start a scan on a connection in the Relyance web application. While it runs, the scanner pods show in the cluster:
kubectl get scaledjobs,pods -n inhostThe scan status shows in the web application. The results show when the scan completes.
What Relyance receives
| Relyance receives | Relyance does not receive |
|---|---|
| Metadata about the connected systems, for example database, table, column, file and service names, and resource titles | Values from the data sources |
| Identity data from identity and access sources, for example users, groups and permissions | The text around matched values |
| Classification results | Credentials for In Host BYOK connections |
| Scan status, counts and timestamps | Logs, metrics or crash reports |
Note. The matched values that the scanner finds are not included in the scan results that Relyance copies.
Security
Identity. The Outpost components keep no long-lived credentials. The scanner pods get the Relyance_Sierra role through EKS Pod Identity. They sign in to the Relyance command queue and API with short-lived credentials from workload identity federation.
Credentials. With In Host BYOK, the credentials stay in a secret in your account. Relyance stores only the secret ARN and rejects credential values for these connections. The scanner reads the secret during the scan with its own role. For the setup steps, refer to Store Outpost Credentials in a Customer-Managed Secret.
Encryption. All connections to Relyance use TLS. A KMS key in your account encrypts the findings bucket and the work bucket.
Access. Relyance has one read-only role, Relyance_Sierra_Reader. It can read the findings bucket only, and only with the external ID from your module. Relyance has no Kubernetes, console or network access to your environment. When the module creates the cluster, it gives cluster administrator access only to the identity that applies it and to the identities that you list in eks_kubectl_admins.
Network. The cluster makes only outbound connections. The VPC that the module creates has outbound internet access through NAT gateways and no inbound path. To limit outbound traffic, allow these destinations:
| Destination | Purpose |
|---|---|
209479300333.dkr.ecr.us-west-2.amazonaws.com, and Amazon S3 in us-west-2 for image layers |
Relyance container registry |
internal.api.relyance.ai |
Control plane API |
sts.googleapis.com, iamcredentials.googleapis.com |
Short-lived credentials for the command queue and API |
pubsub.googleapis.com, monitoring.googleapis.com |
Command queue, and the number of waiting commands |
| AWS APIs in your region: S3, STS, Secrets Manager, KMS | Your buckets, the data source roles and the secrets |
| Your data sources | Scanning |
Data retention in your account
| Data | Default retention | Module variable |
|---|---|---|
| Scan results in the findings bucket | 180 days | s3_expiration_days |
| Temporary scan data in the work bucket | 7 days | s3_workspace_expiration_days |
Versioning is on for both buckets. The lifecycle rules expire the current version of each object. Earlier versions of an object stay until you delete them, or until you add a lifecycle rule for noncurrent versions.
Operations and support
Updates. You control three versions:
| Part | How to update |
|---|---|
| Terraform module | Change version in the module block and apply. |
| Manifests | Change the version in the URLs in kustomization.yaml and the KEDA command, then apply them again. Earlier versions stay available. |
| Scanner images | The manifests use the release tag, so the next scan uses the new scanner version. To apply updates on your own schedule, pin an image digest with an images: entry in kustomization.yaml. |
Monitoring. The deployment sends no logs, metrics or telemetry to Relyance. Logs stay in your cluster. Use your own tools to collect them.
Support. Relyance collects no diagnostic data automatically. Relyance support uses only the diagnostic data that you decide to share.