Azure API Management - Client Certificate Authentication Responsibilities? - azure

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.

Related

Azure APIM - how to validate client certificate using context.Request.Certificate.Verify()

I am trying to validate a client certificate in Azure API management using context.Request.Certificate.Verify() method.
I have tried the following steps:
I have created self signed root CA certificate and then created a
client certificate and key file.
Now from postman, I am trying to call a method attaching the client certificate. I have verified that the certificate is sent to APIM via trace.
Have uploaded the root CA certificate in APIM -> CA certificates. While uploading I
converted to ".cer" file as it is not accepting ".crt" file and set the Store as "Trusted root".
In APIM policy, have used the method to validate the client certificate via context.Request.Certificate.Verify().
Now, when I try to call APIM api with client certificate, the above method (step 4) is always coming as False, verified from apim trace. Not sure, what and where I am doing wrong things. Any help/guidance or any article is really helpful.
I faced the similar issues, Investigation Summary / Cause are below:
Later customer encountered issue again when they sent PFX certificate as a client certificate to APIM from Postman.
The self signed certificate CRL distribution list (Urls in certificate revocation lists) and Access information cannot be publicly reached (APIM is public hosted and not internal) hence certificate.verify fails
2 options to fix the issue
Purchase a certificate from a Public trusted CA
Use context.Request.Certificate.VerifyNoRevocation instead of context.Request.Certificate.Verify so that APIM will not check the revocation list during certificate.verify
Note:
If certificate.verify is a mandatory order from your security team, then you would have to purchase a certificate from trusted CA
o you need to VerifyNoRevocation since apim cannot retrieve revocation list information and VerifyNoRevocation will still perform verifying certificate path as well
For client certificate validation in Azure API management generally following steps are required.
Generate a root CA , intermediate CA along with the client certificates.
Upload the intermediate certificate which validate client certificates sent by the user.
You van utilize this guide to set up the CA.

Client Authentication good enough for k8s?

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.

Securing Service calls from node using ssl

I am trying to securing the service calls that are made from my node to other services secure. All the other services have enabled https. I tried the following methods
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
which as per my understanding ignores all error so removed from the code becuase of certificates
I am using request module. where we can configure
key - provided my private key file,
cert - provided my certificate file
ca - certificate authorty chain
then it was throwing UNABLE_TO_VERIFY_LEAF_SIGNATURE
I found out that node doesn't read ca from the system.
it has its own ca chain So I included node-ssl-root-cas
which fetched latest cas from internet.
Then using ssl-analyser, i was able to find my domain doesn't have intermediate ca certificate
I downloaded that from our ca and made a ca chain and attached it to ssl-root-cas
Then i was able to make requests successfully
But Even if I remove key and cert from my request i am able to make request and get result.
How can I check my request and response are actually encrypted?
Or node just ignoring errors,
FYI, Node will use the certificate auhtorities installed on the system if you don't provide your own with the "ca" property. When you do provide your own, the system ones are ignored. This is by design, as providing your own CA likely means that you want to only trust certificates signed by your own CA. If you aren't using your own CA, you can skip setting the "ca" property. If you are, then I'm not sure why you would need to provide the full list of commonly trusted CAs as well. That seems like a pretty odd use case.
You can use the https module to make requests without providing your own key and cert. This is expected and documented behaviour. For technical reasons, when making any https requests, more specifically opening any TLS socket, the client also needs to have a private key and certificate. In the default case, the server doesn't verify the client in any way, so browsers use what's commonly referred to as a "snakeoil" certificate - a bundled self signed certificate.
The use case for providing your own key and cert when performing https requests, is when the server has client certificate checks enabled. For example, when connecting to Apple's servers for delivering push messages to iOS, you have a client certificate issued by Apple that Apple's servers uses to verify that you have access to send push messages (the certificate was issued by Apple) and which app you are sending to (the fingerprint/checksum of the certificate).
Unless the https services you talk to require specific client certificates, you're better off not setting "key" and "cert" - there's no real reason to do that.
So, in summary, you can probably skip setting all three of key, cert and ca, as the real problem seemed to be your mis-configured server (it didn't serve the CA chain).

What certificate store should I use to store a certificate for signing/encrypting JWT tokens?

I'm adding support for JWT tokens in my Web Application, and I have an X509 certificate which it needs for signing those tokens.
I have rejected the idea of using the same certificate we use for HTTPs (see Can I use the Private Key Certificate of Web App to sign JWT?).
I think a self signed certificate should do the trick, in fact I can't see any advantages of a web of trust in this scenario (that doesn't mean there aren't any, I just can't think of any).
The web application runs on a farm of web servers. My current plan is to generate a self signed cert and put the X509 certificate into the certificate store in Windows on each machine. Our IT department are checking, but they think they can roll that out to all the Web Servers in the farm using Group Policy. So this seems like a feasible plan.
The certificate store in windows looks pretty confusing to me. I think there are two options:
1) Put it in "My" store for the user under which the IIS App pool run. There are many app pools, so potentially the certificate will be in many stores.
2) Put it under the LocalMachine store, and then grant explicit access to the specific certificate for the IIS user(s).
3) Something else I can't think of.
Is there a "correct" place for these type of certs, and if so where is it?
The usual CertificateStore for signing certificates is the My store. I normally place them in LocalMachine location, but it is probably safer to put them in the certificate store for the Application Pool identity itself.
I would then give the Application Pool read-only access to this certificate only (right click certificate, then 'All Tasks' > 'Manage Private Keys', then add your Application Pool identity and give 'Read' permissions only.

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

Resources