Configure media storage
Select a media storage backend on spec.media.storage so the agent’s facade accepts file uploads.
Prerequisites
Section titled “Prerequisites”- An AgentRuntime.
type: noneis the default and disables media storage. - For
local: a ReadWriteMany PersistentVolumeClaim in the agent’s namespace. The agent containers have a read-only root filesystem, solocalneeds a mounted volume. - For
s3,gcsorazure: a bucket or container, and either a workload identity that can reach it or credentials in a Secret.
type | Use case | Credentials |
|---|---|---|
local | Development, single-replica deployments | None |
s3 | AWS, or S3-compatible services such as MinIO | IRSA, EC2 instance profile, or a Secret |
gcs | Google Cloud | Workload Identity (Application Default Credentials) |
azure | Azure | An account key in a Secret |
-
Give the agent pod access to the backend. Skip this step for
local.Annotate the ServiceAccount the pod runs as. To use your own ServiceAccount, set
spec.podOverrides.serviceAccountName.EKS (IRSA):
apiVersion: v1kind: ServiceAccountmetadata:name: omnia-agentannotations:eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/omnia-media-roleThe role needs
s3:PutObject,s3:GetObject,s3:DeleteObjectands3:ListBucketon the bucket (arn:aws:s3:::my-media-bucket) and its objects (arn:aws:s3:::my-media-bucket/*).GKE (Workload Identity):
apiVersion: v1kind: ServiceAccountmetadata:name: omnia-agentannotations:iam.gke.io/gcp-service-account: omnia-media@my-project.iam.gserviceaccount.comGrant the Google service account
roles/storage.objectAdminon the bucket.To use explicit credentials instead, create a Secret and reference it in step 2. An S3 Secret holds the keys
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY. An Azure Secret holds the keyAZURE_ACCOUNT_KEY:apiVersion: v1kind: Secretmetadata:name: azure-storage-keytype: OpaquestringData:AZURE_ACCOUNT_KEY: <your-storage-account-key>Azure always needs the account key. Upload and download URLs are SAS URLs signed with that key, so workload identity alone cannot produce them, even when the pod also uses workload identity.
-
Set
spec.media.storage. Use the block for your backend.Local, with a PVC mounted at
basePathin the facade and runtime containers:apiVersion: omnia.altairalabs.ai/v1alpha1kind: AgentRuntimemetadata:name: my-agentspec:media:storage:type: locallocal:basePath: /var/lib/omnia/mediavolumeClaim: omnia-mediaS3, keyless.
regionis required: the API server rejects ans3backend without one. An S3-compatible service that ignores regions still needs a value, such asus-east-1.spec:media:storage:type: s3s3:bucket: my-media-bucketregion: us-west-2prefix: omnia/media/ # optionalFor MinIO or another S3-compatible service, add
endpoint(this also forces path-style addressing). For explicit credentials, addsecretRef:spec:media:storage:type: s3s3:bucket: my-bucketregion: us-east-1endpoint: http://minio.minio-system:9000secretRef:name: my-s3-credentialsGCS:
spec:media:storage:type: gcsgcs:bucket: my-media-bucketprefix: omnia/media/ # optionalAzure:
spec:media:storage:type: azureazure:account: mystorageaccountcontainer: mediasecretRef:name: azure-storage-key -
Optionally set limits next to
type:maxFileSizeBytes,defaultTTL,uploadURLTTLanddownloadURLTTL. See AgentRuntimemedia.storagefor the fields and defaults. -
Apply the AgentRuntime.
Terminal window kubectl apply -f agentruntime.yaml
Verify
Section titled “Verify”The operator renders the settings into OMNIA_MEDIA_STORAGE_* environment variables on the facade container. List their names:
kubectl get deployment my-agent \ -o jsonpath='{.spec.template.spec.containers[?(@.name=="facade")].env[*].name}'The output includes OMNIA_MEDIA_STORAGE_TYPE. Then confirm the facade started the backend:
kubectl logs deployment/my-agent -c facadeThe log contains a media storage enabled entry with the backend type. To upload a file, follow Upload media to an agent.
Troubleshooting
Section titled “Troubleshooting”The AgentRuntime is rejected with “type s3 requires spec.media.storage.s3.region”
Section titled “The AgentRuntime is rejected with “type s3 requires spec.media.storage.s3.region””The facade needs both a bucket and a region for s3, so the CRD refuses an s3 backend without s3.region. Set it.
Upload fails with “upload not found or expired”
Section titled “Upload fails with “upload not found or expired””The upload URL expired or was already used. The default uploadURLTTL is 15 minutes. Request a new upload URL, or raise uploadURLTTL.
S3 “access denied”
Section titled “S3 “access denied””- Check that the IAM role grants the four actions in step 1.
- Check the IRSA annotation on the ServiceAccount the pod runs as.
- Check that the bucket policy allows the role.
GCS “permission denied”
Section titled “GCS “permission denied””- Check that Workload Identity is configured for the pod’s ServiceAccount.
- Check that the Google service account has
roles/storage.objectAdmin. - Check the bucket IAM bindings.
Azure “SAS URL generation requires shared key credential”
Section titled “Azure “SAS URL generation requires shared key credential””The facade has no account key. Add secretRef to spec.media.storage that points at a Secret with the key AZURE_ACCOUNT_KEY.
Related pages
Section titled “Related pages”- AgentRuntime reference:
media.storage - Media metrics
- Upload media to an agent
- WebSocket flows for the upload sequence