BeeBridge AIBeeBridge AI
API-Referenz
Verwaltungs-APIsVerwaltungs-PATs integrieren und migrieren
⚠️Compliance-Hinweis: Verwenden Sie dieses Projekt nur für rechtmäßig autorisierte API-Gateways, interne Verwaltung und private Bereitstellungen. Beachten Sie die Nutzungsbedingungen vorgelagerter Dienste, Plattformregeln, regulatorische Vorgaben und Anforderungen an die Inhaltssicherheit.

Verwaltungs-PATs integrieren und migrieren

Vollständiger rc.44-Ablauf von Anmeldung und Vorgangsnachweis bis zur einmaligen PAT-Ausstellung

Voraussetzungen

Diese Verwaltungsintegration verwendet https://api.beeaicloud.com. Zuerst Verwaltungsauthentifizierung lesen. PAT-Erstellung und -Verwaltung benötigen eine angemeldete Sitzung, kein vorhandenes PAT. Beispiele verwenden Platzhalter und temporäre Variablen.

Die konkrete Berechtigung binden

Der oberste scope="access_token.generate" bezeichnet die PAT-Erstellung; context.scopes enthält die dem PAT verliehenen Ressourcenrechte. context muss genau scopes und expires_at enthalten. Fehlender Kontext, leere Objekte, falsche Typen, leere Rechte oder zusätzliche Felder werden abgelehnt. Bei Prüfung und Erstellung dieselben Rechte und denselben Unix-Zeitstempel in Sekunden wiederverwenden, nicht neu berechnen. Ein positiver Ablauf muss bei Erstellung mindestens eine Stunde vorausliegen. name umfasst nach Trimmen 1–64 Zeichen und gehört nur in die Erstellung, nicht in den Prüfkontext.

{"method":"password","scope":"access_token.generate","context":{"scopes":["profile:read"],"expires_at":1794679200},"password_encrypted":"<encrypted-password>","encryption_key_id":"<current-kid>"}

Vollständiges Passwortbeispiel

Das Node.js-Beispiel behandelt den aktuellen öffentlichen Schlüssel, v2-Verschlüsselung, Kontoprüfung und identische Berechtigungsbindung. Nur verwenden, wenn password erlaubt ist. Anmelde-MFA, CAPTCHA und andere erforderliche Schritte abschließen statt umgehen. BB_PAT_SCOPES hat standardmäßig nur profile:read. Das PAT wird nicht ausgegeben; pat vor Prozessende mit dem eigenen Geheimnisspeicher verbinden.

import { constants, createCipheriv, publicEncrypt, randomBytes } from 'node:crypto';

const base = 'https://api.beeaicloud.com';
const username = process.env.BB_USERNAME;
const password = process.env.BB_PASSWORD;
const expectedUserID = process.env.BB_EXPECTED_USER_ID;
if (!username || !password || !expectedUserID) throw new Error('Missing account configuration');

async function call(path, { method = 'GET', access, proof, body } = {}) {
  const response = await fetch(base + path, {
    method,
    headers: {
      ...(body ? { 'Content-Type': 'application/json' } : {}),
      ...(access ? { Authorization: `Bearer ${access}` } : {}),
      ...(proof ? { 'X-Security-Proof': proof } : {}),
    },
    ...(body ? { body: JSON.stringify(body) } : {}),
    redirect: 'error',
  });
  const result = await response.json();
  if (!response.ok || result.success !== true) {
    const code = result.code ?? result.data?.code ?? 'REQUEST_REJECTED';
    throw new Error(`${method} ${path}: HTTP ${response.status} ${code}`);
  }
  return result.data;
}

async function passwordFields() {
  const key = await call('/api/user/login/encryption-key');
  if (!key.enabled) return { password };
  const aesKey = randomBytes(32);
  const nonce = randomBytes(12);
  const cipher = createCipheriv('aes-256-gcm', aesKey, nonce);
  cipher.setAAD(Buffer.from(`password-v2:${key.kid}`));
  const ciphertext = Buffer.concat([
    cipher.update(password, 'utf8'), cipher.final(), cipher.getAuthTag(),
  ]);
  const wrappedKey = publicEncrypt({
    key: key.public_key, padding: constants.RSA_PKCS1_OAEP_PADDING,
    oaepHash: 'sha256', oaepLabel: Buffer.from('password-v2'),
  }, aesKey);
  return {
    password_encrypted: ['v2', wrappedKey.toString('base64'),
      nonce.toString('base64'), ciphertext.toString('base64')].join('.'),
    encryption_key_id: key.kid,
  };
}

const login = await call('/api/user/login', {
  method: 'POST', body: { username, ...await passwordFields() },
});
if (login.require_verification || !login.access_token) {
  throw new Error('Complete the required sign-in verification flow first');
}
const access = login.access_token;
const profile = await call('/api/user/self', { access });
if (String(profile.id) !== expectedUserID || profile.username !== username) {
  throw new Error('Account identity mismatch');
}
const catalog = await call('/api/user/access_tokens/catalog', { access });
const grantable = new Set(catalog.groups.flatMap(group => group.resources.flatMap(
  resource => resource.actions.map(action => `${resource.resource}:${action.action}`),
)));
const grant = {
  scopes: JSON.parse(process.env.BB_PAT_SCOPES ?? '["profile:read"]'),
  expires_at: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60,
};
if (!Array.isArray(grant.scopes) || grant.scopes.length === 0 ||
    grant.scopes.some(scope => !grantable.has(scope))) {
  throw new Error('Select grantable permissions from the catalog');
}
const methods = await call('/api/verify/methods?scope=access_token.generate', { access });
if (!methods.methods.some(method => method.method === 'password' && method.available)) {
  throw new Error('Use an available verification method for this account');
}
const verification = await call('/api/verify', {
  method: 'POST', access,
  body: { method: 'password', scope: 'access_token.generate',
    context: grant, ...await passwordFields() },
});
const created = await call('/api/user/access_tokens', {
  method: 'POST', access, proof: verification.proof_token,
  body: { name: 'business-integration', ...grant },
});
const pat = created.token;
// Store pat in your secret manager here. Never log it or blindly retry creation.
console.log({ id: created.item.id, expires_at: created.item.expires_at });

Auflisten, ändern und widerrufen

GET /api/user/access_tokens liefert keinen Klartext. data.token erscheint nur einmal bei Erstellung und kann nicht aus token_ref oder token_hint wiederhergestellt werden. PATCH /api/user/access_tokens/{id} benötigt name; reine Umbenennung braucht keinen Nachweis. Bei scopes-Änderung zuvor access_token.update mit {"token_id":123,"scopes":["profile:read"]} prüfen. DELETE /api/user/access_tokens/{id} benötigt access_token.revoke mit {"token_id":123}. Für das alte PAT DELETE /api/user/access_tokens/legacy mit {"legacy":true} verwenden. Jeder Schreibvorgang benötigt einen eigenen frischen Nachweis.

Fehlerdiagnose

Diese Fehlercodes stammen aus rc.44. HTTP-Status allein belegt keinen Erfolg; ein Aufrufstadium namens password_proof belegt kein falsches Passwort.

CodeBedeutung und Prüfung
SECURITY_CONTEXT_INVALIDHTTP 400: Kontext fehlt oder verletzt das strikte Vorgangsschema.
SECURITY_VERIFICATION_FAILEDPasswort-, Geheimtext- oder Codeprüfung fehlgeschlagen; HTTP 200 mit success=false möglich.
SECURITY_VERIFICATION_FLOW_REQUIREDHTTP 400: Eigener interaktiver Ablauf erforderlich.
AUTH_SESSION_REQUIREDHTTP 403: PAT-Verwaltung erfordert eine Anmeldesitzung.
SECURITY_PROOF_CONTEXT_MISMATCHNachweis und konkrete Vorgangsparameter stimmen nicht überein.
SECURITY_PROOF_EXPIRED / SECURITY_PROOF_CONSUMEDNachweis abgelaufen oder verbraucht; Vorgangsergebnis zuerst abgleichen.
ACCESS_TOKEN_SCOPE_INVALID / ACCESS_TOKEN_SCOPE_FORBIDDENUngültiges oder vom Konto nicht vergebbares Recht.
ACCESS_TOKEN_EXPIRY_INVALID / ACCESS_TOKEN_LIMITAblauf weniger als eine Stunde voraus oder PAT-Anzahl erreicht.

Registrierung und abgeschlossene Initialisierung

Die Initialisierung umfasst Konto erstellen → anmelden → Vorgangsnachweis → PAT erstellen → sicher speichern und Integration prüfen. Ein vorhandenes Konto bedeutet keinen Abschluss. Bestehende alte PATs und neue Ausstellung sind getrennte Abläufe. Beim Fortsetzen das Konto behalten, vorhandene PATs prüfen und nur einen sicher unvollständigen Schritt wiederaufnehmen. Ein unbekanntes Ausstellungsergebnis zuerst abgleichen.

War diese Anleitung hilfreich?

Verwaltungs-PATs integrieren und migrieren | BeeBridge AI