Pulling Secrets in Java on EC2 with IAM

I’ve been reading through the Conjur documentation and I have a conceptual understanding of what I’ve read. But I am missing some connections in my understanding preventing me from being able to put theory into practice.

My goal is simple. I want to get a Java application running on an EC2 instance to pull a secret from a Conjur instance that is also running in EC2. I want to use IAM authentication. Thus far the only code sample I could find that was running on EC2 appeared to be using Conjur authentication instead of IAM Authentication

The TL;DR Version of My Questions

  • How do I enable the Conjur IAM authenticator in the Conjur AWS image? With a policy, an environment variable, or both?
  • Using the Java client library how do I know what values to use to populate a Credentials object?

The Details:

Enabling IAM Authentication

I’ve read the documentation on enabling IAM authentication. The instructions show assigning a value to an environment variable named CONJUR_AUTHENTICATORS before Conjur starts and defining a policy that enables IAM authentication. How does one set an environment variable before Conjur starts using the Conjur AWS image? Or is this something that is already done in the AMI and the policy step is all that is needed?

I setup my instance using the CloudFormation template defined in the quickstart.

Authentication with Java

If my understanding is correct my Java application must query the role that it’s host machine is assigned to by reading from the endpoint http://169.254.169.254/latest/meta-data/iam/info. I believe I am supposed to take the Role ARN and reformat it as {Amazon-Account-ID}/{Role-Name} so that it looks something like this.

000000000000/MyRole

I’m drawing a blank on hot to actually use this though. I looked at the classes in the Java Conjur Client library and I believe that I’m going to be using this with a Credentials object by way of the CONJUR_AUTHN_LOGIN_PROPERTY environment variable. But there are three other environment properties that this class reads from and I don’t know what information should go into populating them. I assume CONJUR_AUTHN_URL_PROPERTY gets the URL to my Conjur instance. I don’t know what CONJUR_APPLIANCE_URL_PROPERTY should contain. And I don’t know what to use as the API Key ( CONJUR_AUTHN_API_KEY_PROPERTY).

Once a Credentials object is correctly populated it looks that I can start retrieving secrets by making a Variables object with it and use retrieveSecret to retrieve the secrets the application is authorized to see.

Hey @Alcedes

How does one set an environment variable before Conjur starts using the Conjur AWS image?

I haven’t worked with the AMI in a long time but I think there’s two ways:

  • In the Conjur docker container running on that host (I think the docker image is called appliance or conjur-appliance) there is a file /opt/conjur/etc/conjur.conf that you can edit and restart conjur (ether the conjur service with sv restart conjur or by restarting the container from host).
  • Setting up the env var for that docker instance and restarting the docker container. I don’t know much about this part but I can look into it if you want.

How do I enable the Conjur IAM authenticator in the Conjur AWS image? With a policy, an environment variable, or both?

Mainly you need the env var, then you configure a policy for “who” has access to “what”.

Using the Java client library how do I know what values to use to populate a Credentials object?

This one is a bit tougher as I know little bits of this-and-that but I’ll try to help. As far as I understand from this Ruby example, you need to:

  • If I’m reading the Ruby code right, you first create a signed AWS API sigv4 request for an empty “GET” request in Java - there’s no Conjur API for this part but there’s some instructions I found a Python example here and you would use AWS Java API for it or maybe even just bash.
  • You connect to Conjur using host/user like the policy specifies (I think you are correct in assuming this is the IAM role - you can get this over API but it doesn’t have to be) and for the API key value, you use the JSON content of the signature headers as far as I can tell.
  • With the API client instantiated, you can then push/pull secrets.

The Java API readme has been updated very recently so I’d look again to see if there’s updated info there, particularly in the examples section here.

But there are three other environment properties that this class reads from and I don’t know what information should go into populating them

The variables in Java API are a bit different from Ruby ones so you need to change them to match this:

export CONJUR_ACCOUNT="<account_specified_during_conjur_setup>"
export CONJUR_APPLIANCE_URL="https://<your_external_ip_or_domain>/api"
export CONJUR_AUTHN_LOGIN="<iam_role>"
export CONJUR_AUTHN_API_KEY="<json_of_sigv4_headers(i_think)>"
export CONJUR_AUTHN_URL ="<appliance_url>/authn-iam/<authenticator_name>"

PS: I also found this doc which talks in very good detail on the inner core of IAM auth that might be of assistance.

Let me know if you have any other questions and if you do get some code working with this, we would love to make it a contribution to our docs, code, and/or API examples!

Srdjan

Thanks, this is useful. I’m trying it out and will post back for the sake of others that might need the information.

1 Like