entity is a full custom COSI-compliant S3 object service for Kubernetes, implemented without MinIO.
Full user documentation (installation, order of operations, TLS modes, scaling, examples):
CI/release workflow:
Helm chart:
Prebuilt Helm chart (GHCR OCI):
oci://ghcr.io/mchenetz/charts/entity
- Custom object server (
cmd/objectd) with:- S3-compatible API (
ListBuckets,Create/DeleteBucket,ListObjectsV2,Put/Get/Head/DeleteObject) - AWS Signature V4 authentication
- Per-bucket scoped access keys and read-only/read-write policies
- S3-compatible API (
- Admin API used by the COSI backend listener
- Operator (
cmd/operator) withObjectServiceCRD that:- Provisions/updates a Portworx-backed StatefulSet
- Creates service and admin token secret
- Reconciles an in-cluster COSI controller deployment
- COSI controller (
cmd/cosidriver) using the upstream COSI API listeners:- Provisions Bucket resources in backend
- Grants/revokes BucketAccess credentials
- Writes workload credentials Secret
- Clustered object layer:
- StatefulSet peer discovery via headless service
- Leader routing for mutating S3/Admin operations
- Synchronous follower replication with quorum checks
- TLS and cert handling:
- Auto-generated and rotated self-signed certs (default)
- Optional cert-manager Certificate reconciliation
- HTTPS for S3/Admin APIs
- mTLS enforcement on intra-cluster replication endpoints
Set spec.storageClassName in ObjectService to your StorageClass (example: px-repl3).
Every object server pod uses a dedicated PVC from that class.
go build ./...
make docker-build IMAGE=ghcr.io/mchenetz/entity:latestmake deployThis applies:
ObjectServiceCRD- COSI CRDs
- RBAC/ServiceAccounts
- Operator deployment
- Sample
ObjectService - Sample COSI classes
Login to GHCR (Helm OCI):
echo <GITHUB_TOKEN> | helm registry login ghcr.io -u <GITHUB_USERNAME> --password-stdinInstall directly from registry:
helm upgrade --install entity oci://ghcr.io/mchenetz/charts/entity \
--version 0.1.0 \
--namespace entity-system --create-namespaceInstall and create ObjectService + COSI classes:
helm upgrade --install entity oci://ghcr.io/mchenetz/charts/entity \
--version 0.1.0 \
--namespace entity-system --create-namespace \
--set image.repository=ghcr.io/mchenetz/entity \
--set image.tag=latest \
--set objectService.create=true \
--set objectService.storageClassName=px-repl3 \
--set cosi.createClasses=trueOptional: pull chart locally first:
helm pull oci://ghcr.io/mchenetz/charts/entity --version 0.1.0
tar -xzf entity-0.1.0.tgz
helm upgrade --install entity ./entity --namespace entity-system --create-namespaceRun the full Kind e2e (build image, deploy stack, create COSI bucket/access, perform S3 put/get/list):
make e2e-kindOptional environment overrides:
KIND_CLUSTER_NAME(defaultentity-e2e)KIND_RECREATE_CLUSTER(defaulttrue)ENTITY_IMAGE(defaultentity:e2e)AWSCLI_IMAGE(defaultamazon/aws-cli:2.17.56)
Default mode: operator-managed certificates.
- Leave
spec.tlsSecretNameunset (or set it to a secret name the operator controls). - Operator creates a TLS secret containing
tls.crt,tls.key, andca.crtand rotates before expiry.
cert-manager mode:
- Set
spec.useCertManager: true - Set
spec.issuerRefName(and optionallyissuerRefKind/issuerRefGroup) - Operator reconciles a
cert-manager.io/v1 Certificatetargetingspec.tlsSecretName.
In both modes, COSI credential secrets include AWS_CA_BUNDLE_PEM for S3 clients.
kubectl apply -f deploy/cosi-claim-example.yamlThen read credentials:
kubectl -n default get secret app-bucket-credentials -o yaml- Operator:
cmd/operator/main.go - Object server:
cmd/objectd/main.go - COSI controller:
cmd/cosidriver/main.go - Reconciler:
controllers/objectservice_controller.go - S3 implementation:
internal/s3 - Metadata/object store:
internal/objectd/store.go - COSI listeners:
internal/cosi/listeners.go
- Current S3 protocol support targets core bucket/object workflows used by workloads and COSI lifecycles.
- Credentials are protocol
S3, authKey, and are bucket-scoped. - Multi-replica clustering is supported; set
spec.replicas> 1.
This project is licensed under AGPL-3.0-only.