Skip to content

Connecting storage (self-hosted) / on-boarding

For OSS self-hosted Cytario deployments that run without the admin portal and connect AWS storage. The operator pre-provisions the OIDC identity provider and the IAM data-plane roles out of band, then lists them in a deploy-time config file. There is no Cytario Admin Role and no runtime role creation in this variant — the automated iam:CreateRole / permissions-boundary machinery of the hosted (SaaS/EE) admin portal does not exist here.

Connecting RustFS (or another S3-compatible) storage instead? See RustFS storage onboarding — the authorization model is customer-managed claim-named groups, not IAM roles.

Using the hosted offering? Storage on-boarding is a guided, one-click flow in the admin portal instead — you do not perform any of the steps below.

Prerequisites

  • An S3 bucket (or S3-compatible endpoint) holding the imagery.
  • A Keycloak realm issuing tokens to cytario-web, reachable by AWS STS.
  • AWS credentials able to create an IAM OIDC provider and IAM roles.

1. Provision the OIDC provider and data-plane roles

Deploy oss-provider-roles.yaml:

aws cloudformation deploy \
  --template-file oss-provider-roles.yaml \
  --stack-name cytario-oss-storage \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides \
    OrgAlias=<your-org-alias> \
    OidcProviderHost=auth.example.com/realms/cytario \
    OidcThumbprint=<sha1-thumbprint-of-issuer-CA> \
    CytarioWebClientId=<cytario-web-client-id> \
    DataBucketArn=arn:aws:s3:::<your-bucket>

This creates:

  • OIDC provider trusting the Keycloak issuer.
  • cytario-oss-readwrite — read/write, sharing-capable. Its trust policy conditions on aws:PrincipalTag/ORG == <org alias>; its inline policy grants S3 read/write plus s3:PutBucketPolicy (all ORG-conditioned).
  • cytario-oss-readonly — read-only, carrying an explicit Deny on all write actions including s3:PutBucketPolicy. The Deny holds even if the role is later added to a broader Allow.

Both roles are created under the reserved path /cytario/provider-roles/.

2. Author the bucket-policy baseline

The bucket policy (and, under SSE-KMS, the CMK key policy) must condition each Allow (s3:ListBucket, s3:GetObject, kms:Decrypt) on aws:PrincipalTag/ORG == <org alias>, plus the per-group tag for group-scoped grants. This is the authoritative cross-tenant boundary for every client, including any direct-federated (Cyberduck) client. cytario-web writes the runtime grant delta under the read/write role; the baseline is your responsibility. Managed statements use the Cytario Sid prefix so they are mergeable and revocable while foreign statements are preserved.

3. Write provider-config.yaml

Copy provider-config.sample.yaml, replace the role ARNs with the stack outputs (ReadWriteRoleArn, ReadOnlyRoleArn), and validate against provider-config.schema.json. Mount it where cytario-web's OSS provider loader expects it. The system accepts only what is declared here — it never accepts a caller-supplied role identifier or endpoint.

A read-only entry MUST set allowsSharing: false and reference the read-only role.

4. Confidential client + distinct Cyberduck client id

Even though the self-hosted variant has no admin-portal Admin Policy, the same two preconditions protect the direct-federated path via the bucket policy and the read-only Deny. Register cytario-web as a confidential OIDC client and give Cyberduck a distinct client id (CYBERDUCK_CLIENT_ID != CLIENT_ID).

5. Verify

The pre-production acceptance harnesses live in the cytario-docs repository under e2e/acceptance/. Both fail closed (non-zero exit) on any failure to prove their assertion:

cd e2e/acceptance && npm install
# Cross-tenant denial (needs two organizations / two buckets configured):
ORG_A_WEB_IDENTITY_TOKEN=... ORG_A_ROLE_ARN=... ORG_B_BUCKET=... npm run cross-tenant
# Confidential client + distinct client id:
OIDC_ISSUER=... CLIENT_ID=... CYBERDUCK_CLIENT_ID=... CLIENT_SECRET=... npm run azp-floor

For health verification, confirm cytario-web can list and read the configured bucket under cytario-oss-readwrite and cannot write under cytario-oss-readonly.

When you stop using a connected account, remember to clean it up — see Disconnecting storage / off-boarding.