Auth Schemes

Auth Schemes allow third party applications to make server-to-server calls to the Elements APIs without needing to login or supply user credentials. Auth Schemes leverage the use of JWTs to accomplish the task. In addition to creating user credentials, it is possible to use the signed JWTs to transparently sync user accounts information with existing services.

Generating Auth Schemes

Generating an Auth scheme consists of generating or supply a private/public key pair and configure the additional metadata in the auth scheme. To begin, open the Elements admin panel and find the section labeled auth.

Auth Scheme

  1. Navigate to the Auth Tab.
  2. Find the button at the top of the Auth Scheme list labeled "Create Auth Scheme"

Now you will see the create auth scheme dialog

Create Auth Scheme

Fill out the following fields

  1. Audience (Name) indicates the matching "aud" field of the JWT. This follows the Name paradigm.
  2. Allowed Issuers is a list of allowed issuers. This is a list of one or more Applications that may support this Auth Scheme. If not tied to a specific Application, then leave this blank. See Applications for more information on the value here.
  3. "Tags" follows the Tags for Auth Schemes.
  4. User Level - this is the maximum user level that the scheme will allow when creating new users in Elements.
  5. Algorithm - this is the signing algorithm used to verify the authenticity of the JWT.
  6. Public Key if supplying your own Public key, then paste it here.
  7. Note: This follows the Java DER format of public keys.
  8. Alternatively, if you want Elements to generate the key pair, select the "Generate Key" option in the upper right corner.

Viewing Generated Key

If you selected the "Generate Key" option, then you will be presetned with the public and private key pair. Elements does not store the private key so take care to store this key in a secure place.

Created Auth

Updating Auth Scheme

Updating an auth scheme is a simple process and operates similarly to the auth creation process.

Auth Scheme Update

  1. Navigate to the Auth Tab.
  2. Find the Auth Scheme you wish to edit, and select "Edit"

Within the Auth Scheme editor, you will see a dialog which will allow you to edit the audience, issuers, tags, and levels.

Auth Scheme Update

  1. Audience (Name) indicates the matching "aud" field of the JWT. This follows the Name paradigm.
  2. Allowed Issuers is a list of allowed issuers. This is a list of one or more Applications that may support this Auth Scheme. If not tied to a specific Application, then leave this blank. See Applications for more information on the value here.
  3. "Tags" follows the Tags paradigm for Auth Schemes.
  4. User Level - this is the maximum user level that the scheme will allow when creating new users in Elements.
  5. Algorithm - this is the signing algorithm used to verify the authenticity of the JWT. Supported Algorithms:
  6. Elliptic Curve 256
  7. Elliptic Curve 384
  8. Elliptic Curve 512
  9. RSA 256
  10. RSA 384
  11. RSA 512
  12. Public Key if supplying your own Public key, then paste it here.
  13. Alternatively, if you want Elements to regenerate the key pair, select the "Generate Key" option in the upper right corner.
  14. IMPORTANT If you regenerate or update the public key, all existing JWTs will be immediately invalidated. Elements does not keep track of a history of keys.

Key Format

Elements is based in Java. Therefore, it supplies keys in formats supplied by the JVM. For easy transport, Elements encodes all keys in base64. In order to import the keys into other applications, it may be necessary to convert to other formats using tools like OpenSSL. This section describes a few use cases in handling the keys.

  • For Public keys, refer to X509EncodedKeySpec detailed documentation.
  • For Private keys, refer to PKCS8EncodedKeySpec for detailed documentation.
  • Elements encodes all keys in base64 format using ASCII-compatible encoding.

Example Public RSA Key:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvD1Iz3zf+MmMTT9Ugovovslyq7Kb/mKPLNlC8KKAH/QhNwuYbLgJclzZ4rySFTxMYRsGxIE1mTDorOhqKhk8WekVJFwPLEVDuP4ABU7QSJeZGnevtCxNC4VYB8ZbI68a1Rm2OFdhiu7cObVNdVioqtW58mltLmIeSHj8gRQKKVDBl4B6xnR1NWvQlvZS7mhBKC4yFP8fM6ihTyhjhkkTeoZrPWZSjaJT0aDdK9n0Cdm3Exr3pN7Fr8TtOl+XHpZ45VXEJqcCBnJHRMTdnfaITkphBDgyiAhAGUGIDQsz/aVEzhTUt7ZIne29faeZ7H7K9GCu+I2E1coNHRZvFDjvPwIDAQAB

Example Private RSA Key

MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8PUjPfN/4yYxNP1SCi+i+yXKrspv+Yo8s2ULwooAf9CE3C5hsuAlyXNnivJIVPExhGwbEgTWZMOis6GoqGTxZ6RUkXA8sRUO4/gAFTtBIl5kad6+0LE0LhVgHxlsjrxrVGbY4V2GK7tw5tU11WKiq1bnyaW0uYh5IePyBFAopUMGXgHrGdHU1a9CW9lLuaEEoLjIU/x8zqKFPKGOGSRN6hms9ZlKNolPRoN0r2fQJ2bcTGvek3sWvxO06X5celnjlVcQmpwIGckdExN2d9ohOSmEEODKICEAZQYgNCzP9pUTOFNS3tkid7b19p5nsfsr0YK74jYTVyg0dFm8UOO8/AgMBAAECggEAP8mEosruGqAxqvuK57IBbKVW9lfQBKPhYJE+3cwzHqDboIuNW0oB6X8NVogP+KI2P7Go2W3ve7nXHsCjOSDUEqOpRmjru1S9XjK0Txgl/HNirlVgdO2OLhlBe2D8AVuU/CF6Xh0+MJZAik2lsd4ZScqi+EJBfTZCjMxyxErGJrlhJt0y7Gtfo9psWzZcNnDyBL+DYfsKyyU6VEpcK5i3Amo+bGGV4bK04m2UcOCjSCPlcSxZQERp1/aUoRDZ/c8CbdSBynNiUVFz8vek5sM4e/BlfYBUgmfsnBkYC1WFognSMPJi7J5mgnb7PIKHTVcJ4GDUv6R5GOsde3RROCfsAQKBgQD1wm6A0Nyf+WnxvfKBZ89MsiA95+3fWa55kFzLOHD5mDIzn9hEOtnJGfrkoRLhfwAgQCL3PYM4F9fbG6qkbHAmc9Kds6n7IMaXVf6EBhMMZ1O7jQ+kn7L4YRtPC8nD8r0qGliGkqQ2HVsikKha/bPgv4CnJDJ4NqVZBB9zP+44GQKBgQDEFUYPPkgERmd+UlgFY8V9zUaqwKLO53DeyFT+96e/kMr8VZ+8ZSDP0oxBOn0QmMjVSkePA2tMWBsI/o0qmJfu4h++EbrZ1w58PTY2kYYqwlek77a7ndx8Damt4zhjmR1br0Gb/Td6JX08oz9i5lPegF8MnpPwnfz5vUdAqlGtFwKBgDJJYJcXJa3OOTFv7okwFqjY4eQI6xGCpkLVmUcz+1n3HH6XvIbpi9qsaDwUAWsGs53lwcHZYlo99rssxBP05FXZ6US/mI58PGaHABc/rvIgym9cA9FppBNSu2XHQbfImZBd57NRmixAgX9nHivQMdhRFyAcNf+HHvpB77WDZVkxAoGAdn40nDmS46J4IEo6judADUnjjoRi3o3WE4sUcg/O+2DQibRkl0C1l2ExCKoDsefiVaJRpAb47GXB0KmjPT6BcgaMEBw+wi3HvyRugoNmhKh0tmN2FeLLvtuy0jYheW6p4yIBj/ZxdAr7p40vXOC7hhYlWkbqN9oBahoL2PQT73kCgYEArMJWc2FFj7NjwJvrUVg0/PxKd5WkE7vlHHaztD1YBrPgNYkaB73aadO75N8go7WEIRCXwjhESGey/zfcAhxj4gTaJIZd9lOd1Mkp+Z5wcuTdm5yieMAGeo+k4UZwjeLT/XPYrlPr3oNVstAJv4eHQpDDvRbVbQcJEqJU/eEkY3Q=

JVM Based Applications

If using Java, Kotlin, or any other JVM based language. Elements keys will integrate seamlessly with a simple conversion. The following demo program shows how the keys can be used to encrypt and decrypt messages.

When using JVM based languages, we recommend using the Auth0 Java JWT library because it has been tested and known to work with Elements. However, we have tested that our JWTs follow the standard specification so any JWT library should work correctly.

package com.namazustudios.socialengine;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class TestKeys {

   private static final String PUBLIC =
           "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvD1Iz3zf+MmMTT9Ugovo" +
           "vslyq7Kb/mKPLNlC8KKAH/QhNwuYbLgJclzZ4rySFTxMYRsGxIE1mTDorOhqKhk8" +
           "WekVJFwPLEVDuP4ABU7QSJeZGnevtCxNC4VYB8ZbI68a1Rm2OFdhiu7cObVNdVio" +
           "qtW58mltLmIeSHj8gRQKKVDBl4B6xnR1NWvQlvZS7mhBKC4yFP8fM6ihTyhjhkkT" +
           "eoZrPWZSjaJT0aDdK9n0Cdm3Exr3pN7Fr8TtOl+XHpZ45VXEJqcCBnJHRMTdnfaI" +
           "TkphBDgyiAhAGUGIDQsz/aVEzhTUt7ZIne29faeZ7H7K9GCu+I2E1coNHRZvFDjv" +
           "PwIDAQAB";

   private static final String PRIVATE = 
           "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8PUjPfN/4yYxN" +
           "P1SCi+i+yXKrspv+Yo8s2ULwooAf9CE3C5hsuAlyXNnivJIVPExhGwbEgTWZMOis" +
           "6GoqGTxZ6RUkXA8sRUO4/gAFTtBIl5kad6+0LE0LhVgHxlsjrxrVGbY4V2GK7tw5" +
           "tU11WKiq1bnyaW0uYh5IePyBFAopUMGXgHrGdHU1a9CW9lLuaEEoLjIU/x8zqKFP" +
           "KGOGSRN6hms9ZlKNolPRoN0r2fQJ2bcTGvek3sWvxO06X5celnjlVcQmpwIGckdE" +
           "xN2d9ohOSmEEODKICEAZQYgNCzP9pUTOFNS3tkid7b19p5nsfsr0YK74jYTVyg0d" +
           "Fm8UOO8/AgMBAAECggEAP8mEosruGqAxqvuK57IBbKVW9lfQBKPhYJE+3cwzHqDb" +
           "oIuNW0oB6X8NVogP+KI2P7Go2W3ve7nXHsCjOSDUEqOpRmjru1S9XjK0Txgl/HNi" +
           "rlVgdO2OLhlBe2D8AVuU/CF6Xh0+MJZAik2lsd4ZScqi+EJBfTZCjMxyxErGJrlh" +
           "Jt0y7Gtfo9psWzZcNnDyBL+DYfsKyyU6VEpcK5i3Amo+bGGV4bK04m2UcOCjSCPl" +
           "cSxZQERp1/aUoRDZ/c8CbdSBynNiUVFz8vek5sM4e/BlfYBUgmfsnBkYC1WFognS" +
           "MPJi7J5mgnb7PIKHTVcJ4GDUv6R5GOsde3RROCfsAQKBgQD1wm6A0Nyf+WnxvfKB" +
           "Z89MsiA95+3fWa55kFzLOHD5mDIzn9hEOtnJGfrkoRLhfwAgQCL3PYM4F9fbG6qk" +
           "bHAmc9Kds6n7IMaXVf6EBhMMZ1O7jQ+kn7L4YRtPC8nD8r0qGliGkqQ2HVsikKha" +
           "/bPgv4CnJDJ4NqVZBB9zP+44GQKBgQDEFUYPPkgERmd+UlgFY8V9zUaqwKLO53De" +
           "yFT+96e/kMr8VZ+8ZSDP0oxBOn0QmMjVSkePA2tMWBsI/o0qmJfu4h++EbrZ1w58" +
           "PTY2kYYqwlek77a7ndx8Damt4zhjmR1br0Gb/Td6JX08oz9i5lPegF8MnpPwnfz5" +
           "vUdAqlGtFwKBgDJJYJcXJa3OOTFv7okwFqjY4eQI6xGCpkLVmUcz+1n3HH6XvIbp" +
           "i9qsaDwUAWsGs53lwcHZYlo99rssxBP05FXZ6US/mI58PGaHABc/rvIgym9cA9Fp" +
           "pBNSu2XHQbfImZBd57NRmixAgX9nHivQMdhRFyAcNf+HHvpB77WDZVkxAoGAdn40" +
           "nDmS46J4IEo6judADUnjjoRi3o3WE4sUcg/O+2DQibRkl0C1l2ExCKoDsefiVaJR" +
           "pAb47GXB0KmjPT6BcgaMEBw+wi3HvyRugoNmhKh0tmN2FeLLvtuy0jYheW6p4yIB" +
           "j/ZxdAr7p40vXOC7hhYlWkbqN9oBahoL2PQT73kCgYEArMJWc2FFj7NjwJvrUVg0" +
           "/PxKd5WkE7vlHHaztD1YBrPgNYkaB73aadO75N8go7WEIRCXwjhESGey/zfcAhxj" +
           "4gTaJIZd9lOd1Mkp+Z5wcuTdm5yieMAGeo+k4UZwjeLT/XPYrlPr3oNVstAJv4eH" +
           "QpDDvRbVbQcJEqJU/eEkY3Q=";

   public static void main(final String[] args) throws Exception {

      final String message = "Hello Encrypted World!";
      final byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);

      final byte[] publicKeyBytes = Base64.getDecoder().decode(PUBLIC);
      final byte[] privateKeyBytes = Base64.getDecoder().decode(PRIVATE);

      final X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes, "RSA");
      final PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes, "RSA");

      final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      final PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
      final PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

      final Cipher ecCipher = Cipher.getInstance("RSA");
      ecCipher.init(Cipher.ENCRYPT_MODE, publicKey);

      final byte[] encryptedMessageBytes = ecCipher.doFinal(messageBytes);
      ecCipher.init(Cipher.DECRYPT_MODE, privateKey);

      final byte[] decryptedMessageBytes = ecCipher.doFinal(encryptedMessageBytes);
      final String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);

      if (!message.equals(decryptedMessage)) {
         throw new IllegalArgumentException("Something wen wrong.");
      }

   }

}