Certificate-based Authentication for S3
Security is paramount at MinIO and sits up there with performance, simplicity and resilience in the pantheon of things that matter.
MinIO encrypts data when stored on disk and when transmitted over the network. MinIO’s state-of-the-art encryption schemes support granular object-level encryption using modern, industry-standard encryption algorithms, such as AES-256-GCM, ChaCha20-Poly1305, and AES-CBC. MinIO is fully compatible with S3 encryption semantics, and also extends S3 by including support for non-AWS key management services such as Hashicorp Vault, Gemalto KeySecure, and Google Secrets Manager.
Given the ubiquity of S3, almost every orchestrated application uses it as the persistence layer. One key questions here is:
How should their authentication flow look like and how should the access credentials be managed?
Since these systems are automated by an orchestrator, like Kubernetes, there is usually no human with some user-specific login credentials. S3 soley relies on authentication using secret keys (AccessKey | SecretKey) shared between the S3 client and the S3 server. However, managing static keys is a security nightmare while manually managing ephemeral keys is an organizational nightmare.
Therefore, the S3 protocol contains an extension - the Secure Token Service (STS) - to request temporal access|secret key pairs from various different credential types. For human authentication, STS supports OpenID Connect (OIDC). But OIDC has an interactive authentication flow and is not suited for automated services.
Hence, MinIO has implemented another STS authentication type: Authentication using client certificates a.k.a. AssumeRoleWithCertificate. Similar to other STS authentication types, an S3 client can request ephemeral S3 access credentials by authenticating itself via X.509 / TLS certificates.
The S3 Client has a TLS client certificate issued by a certificate authority (CA) and hits the AssumeRoleWithCertificate API. The S3 server receives the client certificate as part of the HTTPS connection establishment and verifies that its authenticity - i.e. verifies whether it has been issued by a trusted CA.
Then, the S3 server maps the certificate to an S3 policy using the certificate common name (CN). For example, a certificate issued for the CN my-demo-app will be mapped to the my-demo-app S3 policy. If such a policy exists, the S3 server generates a new ephemeral access | secret key pair associated with the mapped S3 policy and sends the key pair to the client. Finally, the S3 client can perform S3 operations - like up- or downloading data - using the received temporal credentials.
This authentication workflow has various advantages, especially for automated applications:
- Certificate-based authentication requires a TLS connection. The S3 access credentials cannot be leaked over an insecure network connection.
- Certificates are the standard way to prove the identity of a service on the internet, and therefore, widely supported across SDKs and programming languages.
- Certificate-based authentication is "offline" in the sense that the CA does not need to be online whenever an authentication happens. This improves the availability / fault tolerance of the entire system.
- Certificates are itself temporal. They expire and become invalid. Also, a new certificate can be requested whenever needed.
In particular, Kubernetes provides a certificate API for requesting and issuing certificates to pods. This makes it quite easy to provision applications running as pods on Kubernetes with certificates. With this implementation, applications can use their certificates to authenticate to MinIO as their S3 persistence layer. This type of identity-based authentication reduces a lot of organizational headaches when it comes to service-to-service authentication and is very easy to adopt and use by S3 clients.
If you want to take a closer look at the STS API for certificates or concrete configuration take a look at our AssumeRoleWithCertificate documentation.