Key Trustee

Quick Start


For Application Integrators:

We've built a demo project you can use to see a working Key Trustee integration.
  1. Log into Key Trustee and create an application on the Applications screen in the developer section with your application's name, allowed ip addresses and OAuth client IDs then set the application to active. Record the application ID for later use.
  2. Update your service to use the Key Trustee API endpoint:
    https://app.keytrustee.org/api/completions
  3. Add the following headers to your requests:
    • Authorization: Bearer {idToken}
    • X-Auth-Token: The user's auth token.
    • X-KeyTrustee-Application-Id: The application ID (as a number) for your application in Key Trustee.
  4. Use the user's OAuth id token in the Authorization header instead of your API key. Optionally, use the strong_model and weak_model parameters to optimize model selection based on the prompt.
  5. Optional: give the user a link to Key Trustee with your application_id as a query parameter to make it easy for them to configure your application. For example:
    http://app.keytrustee.org?application_id={your_application_id}
  6. Optional: we cache token verifications for 2 hours, so if your application has long lasting sessions, you will need to periodically retrieve new tokens for the user. There are two ways to deal with this:
    1. You can use a refresh token to periodically generate new id and access tokens. This method is less secure for users and shouldn't be used unless you already have a reason for refresh tokens.
    2. We send a 401 "Expired Token" response, you can catch that in the client and pop up a small modal dialog prompting the user to re-authenticate in response. That modal prompt can trigger an OAuth popup, enabling you to get new tokens without losing application state.
    response
Show Python Example (Non-Streaming)

import requests

url = "https://app.keytrustee.org/"
headers = {
    "Authorization": f"Bearer {idToken}",
    "X-Auth-Token": authToken,
    "X-KeyTrustee-Application-Id": 123,  # Replace with your actual application ID
    "Content-Type": "application/json"
}
data = {
    "messages": [{"role": "user", "content": inputText}],
    "model": "gpt-4o-mini-2024-07-18",
    "stream": False
}

response = requests.post(url, headers=headers, json=data)
print(response.json())
                    
Show JavaScript Example (Non-Streaming)

const response = await fetch("https://app.keytrustee.org/api/completions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${idToken}`,
    "X-Auth-Token": authToken,
    "X-KeyTrustee-Application-Id": 2,  // Replace with your actual application ID
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    messages: [{ role: "user", content: inputText }],
    model: "gpt-4o-mini-2024-07-18",
    stream: false,
  }),
});

const result = await response.json();
console.log(result);
                    
Show Python Example (Streaming)

import requests
from time import sleep

url = "https://app.keytrustee.org/api/completions"
headers = {
    "Authorization": f"Bearer {idToken}",
    "X-Auth-Token": authToken,
    "X-KeyTrustee-Application-Id": 123,  # Replace with your actual application ID
    "Content-Type": "application/json"
}
data = {
    "messages": [{"role": "user", "content": inputText}],
    "model": "gpt-4o-mini-2024-07-18",
    "stream": True
}

with requests.post(url, headers=headers, json=data, stream=True) as response:
    if response.status_code != 200:
        raise Exception(f"HTTP error! status: {response.status_code}")
    buffer = ""
    for chunk in response.iter_content(chunk_size=None):
        if chunk:
            buffer += chunk.decode('utf-8')
            while "}{" in buffer:
                json_str, buffer = buffer.split("}{", 1)
                json_str += "}"
                try:
                    chunk_data = json.loads(json_str)
                    if "choices" in chunk_data:
                        content = chunk_data['choices'][0]['delta'].get('content', '')
                        print(content, end='', flush=True)
                except Exception as e:
                    print(f"Error parsing JSON: {e}")
    if buffer:
        chunk_data = json.loads(buffer)
        content = chunk_data['choices'][0]['delta'].get('content', '')
        print(content)
                    
Show JavaScript Example (Streaming)

async function startChatStreaming() {
  const inputText = document.getElementById("inputText").value;
  const outputText = document.getElementById("outputText");

  const idToken = localStorage.getItem("idToken");
  const authToken = localStorage.getItem("authToken");

  const response = await fetch("https://app.keytrustee.org/api/completions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${idToken}`,
      "X-Auth-Token": authToken,
      "X-KeyTrustee-Application-Id": "123",  // Replace with your actual application ID
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      messages: [{ role: "user", content: inputText }],
      model: "gpt-4o-mini-2024-07-18",
      stream: true,
    }),
  });

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const reader = response.body.getReader();
  const decoder = new TextDecoder("utf-8");
  let buffer = "";

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    buffer += decoder.decode(value, { stream: true });
    
    let boundary;
    while ((boundary = buffer.indexOf("}{")) !== -1) {
      const jsonString = buffer.substring(0, boundary + 1).trim();
      buffer = buffer.slice(boundary + 1);

      try {
        const chunk = JSON.parse(jsonString);
        if (chunk.choices && chunk.choices[0] && chunk.choices[0].delta.content) {
          outputText.textContent += chunk.choices[0].delta.content;
        }
      } catch (e) {
        console.error("Error parsing JSON:", e);
      }
    }
  }
  
  if (buffer.length > 0) {
    try {
      const chunk = JSON.parse(buffer.trim());
      if (chunk.choices[0].delta.content) {
        outputText.textContent += chunk.choices[0].delta.content;
      }
    } catch (e) {
      console.error("Error parsing JSON:", e);
    }
  }
}
                    

For Users:

  1. Log into Key Trustee with your primary identity provider.
  2. Add your credit card information to purchase credits. Adding credits is optional, but without credits you'll need API keys to use AI services, and you'll need to override the default model for your applications to ensure they use a configured API.
  3. Add keys for the services you wish to use on the Provider screen.
  4. Make sure your keys are always available in your applicationos by adding any additional identity providers on the Identities page. If you don't do this, applications that don't support authentication with your primary identity provider won't be able to use AI.
  5. Enable AI in your applications on the Application screen of the user section. If you didn't add credits, make sure to select a model from a provider that you've configured an API key with.
Support is available via Discord.
© 2024 Sibylline Software. All rights reserved.