Client Authentication good enough for k8s? - security

I'm trying to secure my k8s cluster, and I'm looking at client-authentication authorization support for k8s. My requirement is that I want to be able to uniquely identify myself (e.g. client) to the k8s apiserver, but everything I read so far about client authentication is not the solution.
My understanding is that the server will just ensure that the client certificate provided is in fact signed by the certificate authority. What if a hacker gets another certificate signed by the same certificate authority (which isn't hard to do in my org) and uses that to talk to my server? It appears that popular orchestrations like Swarm and k8s support this option and touted it as most secure so there must be a reason for doing this. Can someone shed some light?

It is not only verified that the certificate is authorized by the CA. The client certificate also contains the Common Name (CN) which can be used with a simple ABAC Authorization to limit the access to specific users or groups.
Also it shouldn't be easy to get a signed certificate. IMO the access to the root CA should be very limited and it should be comprehensible who is allowed to sign certs and when it happened. Ideally the root CA should life on a offline host.
Beside that it sounds like the CA is also used for other purposes. If it is so, you could consider to create a separate root cert for the client authentication. You can use a different CA for the server certificate by setting different CA files for --client-ca-file and --tls-ca-file on the apiserver. That way you can restrict who is able to create client certificates and still verify the server identity with the CA of your organization (which might already be distributed on all org computers).
Other Authentication Methods
As mentioned Kubernetes also has some other authenication methods. The static token file and the static password file have the disadvantage that the secrets have to be stored plain text on the disk. Also the apiserver has to be restarted on every change.
Service account tokens are designated to be used by applications which run in the cluster.
OpenID might be a secure alternative to client certificates, but AFAIK it is way harder to set up. Especially when there is no OpenID server, yet.
I don't know much about the other authenication methods, but they look like they are intended for integrating with existing single-sign-on services.

Related

Azure API Management - Client Certificate Authentication Responsibilities?

When using Azure API Management Gateway its possible to implement client certification authentication to secure access to APIs. You can validate incoming request certs using policy expressions such as thumb checks etc.
When using client cert authentication method, what's the recommended process for certificate generation/management?
Cert responsibility?
Should I/gateway owner be generating the .pfx file (either self signed or by trusted CA), importing it to the gateway service and providing external clients with the .cer to install locally and auth with?
Should I/gateway owner be generating the .pfx file (either self signed or by trusted CA), importing the .pfx to the API Management gateway service (normally I'd imagine importing the .cer on a server/gateway but doesn't seem possible in Azure) and providing external clients with the .pfx to install locally and auth with?
Should the external client be responsible for generating their public/private key pair in their Org, signing it with a CA, installing it locally and providing me/gateway owner with a .cer file to import to the gateway (as above, not sure its possible to import .cer, I read only .pfx accepted in import process) or provide thumb for me to store/validate in policy?
Does anyone have any advice whether to issue clients requiring access to the same API the same (shared) cert or generate a new cert per client? They would all be using the cert to access the same API (+ additional auth methods, cert is just an extra step).
I've ready online tutorials describing all above bullets and where client-specific or single cert-per-API have been implemented so a little confused which is recommended approach?
The easiest way would be to have a single issuing CA certificate, you'd only need to upload its public key to APIM as that is all that's needed for APIM to validate incoming certificate. Then you'll be responsible to generate client certificates and distribute them to clients. In APIM you can setup a policy that would require certificate, check its issuer and validate, that should be enough to ensure that certificate is valid and issued by you.
Relying on self-signed certificates will be a hassle as you'd have to somehow let APIM know of each new certificate, having common issuing CA frees you of that worry.
Same goes for allowing remote clients to generate certificate - they would have to let you know of certificate and you'd need to list it in APIM one way or another.
You're free to decide how exactly to distribute certificates, a few things to consider:
Likely certificate will be your main way to tell clients apart. If that is important you may want to have different clients have different certificates.
If you want to deny access to a particular client you'll "revoke" that certificate, you need to make sure that other legitimate clients won't be affected.

Azure API Management - Authentication: OAuth2 vs Certificate

I would like to have your mind about an implementation. Thank you in advance for any suggestion :)
**Scenario**
I have a set of APIs. They are accessible via REST and protected by OAuth2. I have also a list of machines that needs to access them.
Question
On machine’s side, which is the best solution to access them? Should I implement a client certificate authentication or OAuth2 is a suitable solution?
**My doubts:**
In case of hundreds, thousands of machines, the certificate
management become too complex/costly?
Should I use a certificate for each machine or one certificate for more than one?
How can I deploy smartly the certificate to each machine?
I like the idea to have the mutual authentication, but I’m afraid is to heavy to maintain compared to the OAuth structure. I plan to use Microsoft Azure as cloud service.
Thanks!
I would say the important factors here are client identity and privilege:
You may have many client machines
But do they represent a single identity, eg a cluster?
And do they all have the same privilege?
By default I would aim for a solution where all client machines with the same privilege present the same credential / identity. The APIs can then authorize requests based on the client identity, provided in the access token.
The standard OAuth solution is Client Credentials flow, where clients each send a secret to the server.
If required (and supported by your Authorization Server) you can use a Mutual TLS form of Client Credentials, via the Client Assertion Profile. This usually boils down to a private key signature sent by the client, which is contained in a whitelist configured on the Authorization Server.

IdentityServer4 signing credential: using publicly available certificate + key?

We currently only use reference tokens as access tokens. This has me wondering if we could just skip the entire certificate management hell by including a self-signed X509 certificate with a ridiculously long validity and store it with our source code (private github) - stop screaming, this might make sense soon.
The worst case I see would be that someone with access to the private key (i.e. any employee or force with access to our github repository) could issue any JWT and use that in the client (angular) - but that's client-side. The APIs are protected via IdentityServer Access Token Validation and all clients are configured to use reference tokens.
Another possible pitfall would be if we ever added a client that uses JWT for access tokens, but I don't really see that happening.
To me, using a long lived self-signed certificate under source-control seems to be the easiest and okay(-ish) solution for this case - unless I've overlooked something. We would never do that with SSL certificates or similar. I'm focussing only on the IdentityServer4 signing credential in combination with exclusive use of reference tokens.
Otherwise we'll have to somehow get certificate rollover (at runtime), certificate management etc. running. I guess we could implement ISigningCredentialStore to manage where the certificates are loaded from - but that still leaves us with the issue on how to handle certificates in a Docker swarm (or just plain Docker containers).
Am I missing something here? Would this solution have any flaws?
Could you not just look it up?
like this
var cert = new CertificateService().GetCertificate(appSettings.CertificateName, StoreName.TrustedPeople, StoreLocation.LocalMachine);
services
.AddSigningCredential(cert);

Using the same server SSL certificate for multiple purposes

We have a backend server that services a multi-platform app that will be launched on iOS, Windows 8, Windows Phone 8 and Android. We'd like to use in production as few certificates as possible (preferably just one) to attain the following purposes:
secure communication (HTTPS) with the client application
authentication to the Windows Phone Push Notifications Service
authentication to the Apple Push Notifications Service
Besides taking care that the certificate is issued by a common trusted root authority, are there any other impediments that could prevent a single certificate from being used simultaneously for all these? Is it a viable possibility or is it instead necessary to resort to one certificate for each of the above purposes?
Gabriel I guess there is a problem. Main one is that HTTPS certificate private key cannot be coded by a secret this kind of certificate contain *.crt and *.key file which are not secured. When You want authenticate yourself or server in some Service for example Windows phone push like you have listed there is need to create hash for your private key with secret aka pin or password. What make You use at least two different certificates.
Second thing is that purpose of using certificates is to validate the issuer and to authenticate user/service provider. HTTPS ssl certificate issued by a trusted CA show to the user Hey this is trusted website You should not be afraid passing sensitive data through the service, and the certificates which are used to authenticate are just saying Hey its me I am authorized to use this application Purpose of those certificates and different so certificates them self should be different. Using the same cert for actions like You have listed cause necessaries vulnerabilities and is highly NOT RECOMMENDED

server-to-server REST API security

We're building a REST API that will only be accessed from a known set of servers. My question is, if there is no access directly from any browser based clients, what security mechanisms are required.
Currently Have:
Obviously over HTTPS
Have HTTP auth enabled, API consumers have a Key & password
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed for the request and validated at the endpoint?
Use OAuth (2-legged authentication)?
Doesn't matter - from browser or not.
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed
for the request and validated at the endpoint?
Use oauth (2-legged authorization)?
Use OAuth, it solves both these questions. And OAuth usage is good because:
You aren't reinventing wheel
There are already a lot of libraries and approaches depending on technology stack
You can also use JWT token to pass some security context with custom claims from service to service.
Also as reference you can look how different providers solve the problem. For example Azure Active Directory has on behalf flow for this purpose
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-on-behalf-of-flow
Use of OAuth2/OpenID Connect is not mandatory between your services, there are other protocols and alternatives and even custom. All depends in which relationships are services and either they both are in full trust environment.
You can use anything you like but main idea not to share sensitive information between services like service account credentials or user credentials.
If REST API security is main requirement - OAuth2/OpenID Connect is maybe the best choice, if you need just secure (in a sense of authentication) calls in full trust environment in a simplest way - Kerberos, if you need encrypted custom tunnel between them for data in transit encryption - other options like VPN. It does not make sense to implement somthing custom because if you have Service A and Service B, and would like to make sure call between them is authenticated, then to avoid coupling and sharing senstive information you will always need some central service C as Identity provider. So if you think from tis pov, OAuth2/OIDC is not overkill
Whether the consumers of your API are web browsers or servers you don't control doesn't change the security picture.
If you are using HTTPs and clients already have a key/password then it isn't clear what kind of attack any other mechanism would protect against.
Any compromise on the client side will expose everything anyway.
Firstly - it matters whether a user agent (such as a browser) is involved in call.
If there are only S2S calls then 1 way SSL HTTPS (for network encryption) and some kind of signature mechanism (SHA-256) should be enough for your security.
However if you return sensitive information in your api response, its always better to accept 2 way ssl HTTPS connections (in order to validate the client).
OAuth2 doesn't add any value in a server to server call (that takes place without user consent and without any user agent present).
For authentication between servers:
Authentication
Known servers:
use TLS with X.509 client certificates (TLS with mutual authentication).
issue the client certificates with a common CA (certificate authority). That way, the servers need only have the CA certificate or public key in the truststore, and new client certificates for additional clients/servers can be issued without having to update the truststores.
Open set of servers:
use API keys, issued by a central authority. The servers need to validate these keys on each request (and may cache the hashes of the keys along with the validation result for some short time).
Identity propagation
if the requests are executed in the context of a non-technical user, use JWT (or SAML) for identity propagation of the user principal and claims (authorize at security proxy/WAF/IAM, and issue JWT signed by authentication server).
otherwise the user principal refers to the technical user and can can be extracted from the client certificate (X.509 DName) or be returned with a successful authentication response (API key case).

Resources