Getting Data In

Store an API Key encrypted

btorresgil
Builder

I'm trying to create a setup.xml for my app that takes in an API key as an input from the user. I have it working for credentials using the 'admin/passwords' endpoint. I tried using the same endpoint to store an API Key as a password, but it doesn't work because I need a username also, and there isn't one. I wouldn't mind storing something in the name field, but I don't want the user to have to input it. I have two ideas on how to solve this problem, but not sure which are possible...

Idea 1: Use a hidden input in setup.xml to fill the name field with a static value like 'apikey'. But I don't think splunk supports hidden inputs in setup.xml?

Idea 2: Create a custom endpoint. But I need the api key to be stored encrypted, and I'm not sure the best way to handle this with a custom endpoint.

Tags (4)
1 Solution

btorresgil
Builder

I came up with a way to do this. I added the following to my setup.xml file:

<block title="API Key" endpoint="storage/passwords" entity="_new">
    <text>Enter your API Key here</text>
          <input field="name">
                  <label>API Key Username (enter api_key as the username)</label>
                  <type>text</type>
          </input>
          <input field="password">
                  <label>API Key</label>
                  <type>text</type>
          </input>
          <text><![CDATA[ <script type="text/javascript">
            $(function(){
                var username_div = $('#item-\\/storage\\/passwords\\/_new\\/name');
                username_div.hide();
                var username_input = $('#\\/storage\\/passwords\\/_new\\/name_id');
                username_input.val('api_key');
            });
          </script> ]]></text>
  </block>

I'm using the storage/passwords endpoint because it automatically encrypts the password. The problem was that it requires a username. Since I'm using this for an API Key, there is not a username. So I added the javascript above to account for the username. The javascript here does two things:

  1. Hides the Username field so it isn't visible in the setup page.
  2. Sets the username to the value 'api_key' which makes it possible to distinguish this credential from other stored credentials.

To get the API Key for use in a python script, I use the technique found in this Splunk blog entry and documentation:
http://blogs.splunk.com/2011/03/15/storing-encrypted-credentials/
http://docs.splunk.com/Documentation/Splunk/5.0.3/AdvancedDev/SetupExampleCredentials

The only difference is the line that says:

return c['username'], c['clear_password']

I have replaced with the following:

if c['username'] == 'api_key':
    return c['clear_password']

View solution in original post

robertlight
Path Finder

Here is how I store my SMTP_PASSWORD

            try:     #attempt it (exception if not already there)
                ent=entity.getEntity("storage/passwords","SMTP_PASSWORD", 
                    namespace=self.getAppName(), owner='smartwall',
                    sessionKey=cherrypy.session['sessionKey'])
                ent['password']=  .... clear text password here....
                ent['clear_password'] = None
                ent['encr_password']  = None
                ent['username']       = None
                entity.setEntity(ent)
            except Exception as e:   #create a new one
                logger.info("SMTP_PASSWORD does not exist, try creating a new one")
                ent = entity.Entity("storage/passwords", "SMTP_PASSWORD", 
                          namespace=self.getAppName(), owner='smartwall')
                ent['password'] = ....clear text password here....
                ent['name'] = "SMTP_PASSWORD"
                entity.setEntity(ent)
0 Karma

btorresgil
Builder

I came up with a way to do this. I added the following to my setup.xml file:

<block title="API Key" endpoint="storage/passwords" entity="_new">
    <text>Enter your API Key here</text>
          <input field="name">
                  <label>API Key Username (enter api_key as the username)</label>
                  <type>text</type>
          </input>
          <input field="password">
                  <label>API Key</label>
                  <type>text</type>
          </input>
          <text><![CDATA[ <script type="text/javascript">
            $(function(){
                var username_div = $('#item-\\/storage\\/passwords\\/_new\\/name');
                username_div.hide();
                var username_input = $('#\\/storage\\/passwords\\/_new\\/name_id');
                username_input.val('api_key');
            });
          </script> ]]></text>
  </block>

I'm using the storage/passwords endpoint because it automatically encrypts the password. The problem was that it requires a username. Since I'm using this for an API Key, there is not a username. So I added the javascript above to account for the username. The javascript here does two things:

  1. Hides the Username field so it isn't visible in the setup page.
  2. Sets the username to the value 'api_key' which makes it possible to distinguish this credential from other stored credentials.

To get the API Key for use in a python script, I use the technique found in this Splunk blog entry and documentation:
http://blogs.splunk.com/2011/03/15/storing-encrypted-credentials/
http://docs.splunk.com/Documentation/Splunk/5.0.3/AdvancedDev/SetupExampleCredentials

The only difference is the line that says:

return c['username'], c['clear_password']

I have replaced with the following:

if c['username'] == 'api_key':
    return c['clear_password']

monzy
Communicator

i would suggest that you have the user input the api key the same way as the user inputs the username and password. in the case of the apikey, you can give them a hint to have a username called, _api_key.

0 Karma

monzy
Communicator

yeah. just give them an additional field called, api_user or something. this will make it easier for you to find the associated api_key.

0 Karma

btorresgil
Builder

Thanks monzy, do you mean to have a username field above the API key field and tell the user to enter a specific user name? I'm trying to avoid potential problems by having only one field in the setup screen, just for the API key. I think a username field would be confusing.

0 Karma
Get Updates on the Splunk Community!

Enterprise Security Content Update (ESCU) | New Releases

In November, the Splunk Threat Research Team had one release of new security content via the Enterprise ...

Index This | Divide 100 by half. What do you get?

November 2024 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with this ...

Stay Connected: Your Guide to December Tech Talks, Office Hours, and Webinars!

❄️ Celebrate the season with our December lineup of Community Office Hours, Tech Talks, and Webinars! ...