diff --git a/autogpt_platform/frontend/src/app/profile/page.tsx b/autogpt_platform/frontend/src/app/profile/page.tsx
index 155b5e04de31..e368bb69846b 100644
--- a/autogpt_platform/frontend/src/app/profile/page.tsx
+++ b/autogpt_platform/frontend/src/app/profile/page.tsx
@@ -20,6 +20,7 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
+import { APIKeysSection } from "@/components/profile/api-keys-section";
import { CredentialsProviderName } from "@/lib/autogpt-server-api";
export default function PrivatePage() {
@@ -112,6 +113,8 @@ export default function PrivatePage() {
+
+
Connections & Credentials
diff --git a/autogpt_platform/frontend/src/components/profile/api-keys-section.tsx b/autogpt_platform/frontend/src/components/profile/api-keys-section.tsx
new file mode 100644
index 000000000000..ad6389eadd6d
--- /dev/null
+++ b/autogpt_platform/frontend/src/components/profile/api-keys-section.tsx
@@ -0,0 +1,289 @@
+"use client";
+
+import { useState, useEffect } from "react";
+import { useToast } from "../ui/use-toast";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "../ui/card";
+import { Button } from "../ui/button";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "../ui/dialog";
+import { Input } from "../ui/input";
+import { Label } from "../ui/label";
+import { Checkbox } from "../ui/checkbox";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "../ui/table";
+import { APIKey, APIKeyPermission } from "@/lib/autogpt-server-api/types";
+import AutoGPTServerAPI from "@/lib/autogpt-server-api/client";
+import { Badge } from "../ui/badge";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "../ui/dropdown-menu";
+import { LuMoreVertical, LuCopy } from "react-icons/lu";
+import { Loader2 } from "lucide-react";
+
+export function APIKeysSection() {
+ const [apiKeys, setApiKeys] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const [isCreateOpen, setIsCreateOpen] = useState(false);
+ const [isKeyDialogOpen, setIsKeyDialogOpen] = useState(false);
+ const [newKeyName, setNewKeyName] = useState("");
+ const [newKeyDescription, setNewKeyDescription] = useState("");
+ const [newApiKey, setNewApiKey] = useState("");
+ const [selectedPermissions, setSelectedPermissions] = useState<
+ APIKeyPermission[]
+ >([]);
+ const { toast } = useToast();
+ const api = new AutoGPTServerAPI();
+
+ useEffect(() => {
+ loadAPIKeys();
+ });
+
+ const loadAPIKeys = async () => {
+ setIsLoading(true);
+ try {
+ const keys = await api.listAPIKeys();
+ setApiKeys(keys.filter((key) => key.status === "ACTIVE"));
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const handleCreateKey = async () => {
+ try {
+ const response = await api.createAPIKey(
+ newKeyName,
+ selectedPermissions,
+ newKeyDescription,
+ );
+
+ setNewApiKey(response.plain_text_key);
+ setIsCreateOpen(false);
+ setIsKeyDialogOpen(true);
+ loadAPIKeys();
+ } catch (error) {
+ toast({
+ title: "Error",
+ description: "Failed to create AutoGPT Platform API key",
+ variant: "destructive",
+ });
+ }
+ };
+
+ const handleCopyKey = () => {
+ navigator.clipboard.writeText(newApiKey);
+ toast({
+ title: "Copied",
+ description: "AutoGPT Platform API key copied to clipboard",
+ });
+ };
+
+ const handleRevokeKey = async (keyId: string) => {
+ try {
+ await api.revokeAPIKey(keyId);
+ toast({
+ title: "Success",
+ description: "AutoGPT Platform API key revoked successfully",
+ });
+ loadAPIKeys();
+ } catch (error) {
+ toast({
+ title: "Error",
+ description: "Failed to revoke AutoGPT Platform API key",
+ variant: "destructive",
+ });
+ }
+ };
+
+ return (
+
+
+ AutoGPT Platform API Keys
+
+ Manage your AutoGPT Platform API keys for programmatic access
+
+
+
+
+
+
+
+
+
+ {isLoading ? (
+
+
+
+ ) : (
+ apiKeys.length > 0 && (
+
+
+
+ Name
+ API Key
+ Status
+ Created
+ Last Used
+
+
+
+
+ {apiKeys.map((key) => (
+
+ {key.name}
+
+
+ {`${key.prefix}******************${key.postfix}`}
+
+
+
+
+ {key.status}
+
+
+
+ {new Date(key.created_at).toLocaleDateString()}
+
+
+ {key.last_used_at
+ ? new Date(key.last_used_at).toLocaleDateString()
+ : "Never"}
+
+
+
+
+
+
+
+ handleRevokeKey(key.id)}
+ >
+ Revoke
+
+
+
+
+
+ ))}
+
+
+ )
+ )}
+
+
+ );
+}
diff --git a/autogpt_platform/frontend/src/lib/autogpt-server-api/baseClient.ts b/autogpt_platform/frontend/src/lib/autogpt-server-api/baseClient.ts
index 12b45ebfca53..122398b4ef10 100644
--- a/autogpt_platform/frontend/src/lib/autogpt-server-api/baseClient.ts
+++ b/autogpt_platform/frontend/src/lib/autogpt-server-api/baseClient.ts
@@ -16,6 +16,9 @@ import {
NodeExecutionResult,
OAuth2Credentials,
User,
+ APIKeyPermission,
+ CreateAPIKeyResponse,
+ APIKey,
ScheduleCreatable,
ScheduleUpdateable,
} from "./types";
@@ -240,6 +243,35 @@ export default class BaseAutoGPTServerAPI {
return this._request("GET", path, query);
}
+ // API Key related requests
+ async createAPIKey(
+ name: string,
+ permissions: APIKeyPermission[],
+ description?: string,
+ ): Promise {
+ return this._request("POST", "/api-keys", {
+ name,
+ permissions,
+ description,
+ });
+ }
+
+ async listAPIKeys(): Promise {
+ return this._get("/api-keys");
+ }
+
+ async revokeAPIKey(keyId: string): Promise {
+ return this._request("DELETE", `/api-keys/${keyId}`);
+ }
+
+ async updateAPIKeyPermissions(
+ keyId: string,
+ permissions: APIKeyPermission[],
+ ): Promise {
+ return this._request("PUT", `/api-keys/${keyId}/permissions`, {
+ permissions,
+ });
+
// Scheduling request
async createSchedule(
graphId: string,
@@ -263,6 +295,7 @@ export default class BaseAutoGPTServerAPI {
async getSchedules(graphId: string): Promise<{ [key: string]: string }> {
return this._get(`/graphs/${graphId}/schedules`);
+
}
private async _request(
diff --git a/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts b/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts
index a416b244fa80..2412c59f0f6e 100644
--- a/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts
+++ b/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts
@@ -330,6 +330,40 @@ export type AnalyticsDetails = {
index: string;
};
+
+// API Key Types
+
+export enum APIKeyPermission {
+ EXECUTE_GRAPH = "EXECUTE_GRAPH",
+ READ_GRAPH = "READ_GRAPH",
+ EXECUTE_BLOCK = "EXECUTE_BLOCK",
+ READ_BLOCK = "READ_BLOCK",
+}
+
+export enum APIKeyStatus {
+ ACTIVE = "ACTIVE",
+ REVOKED = "REVOKED",
+ SUSPENDED = "SUSPENDED",
+}
+
+export interface APIKey {
+ id: string;
+ name: string;
+ prefix: string;
+ postfix: string;
+ status: APIKeyStatus;
+ permissions: APIKeyPermission[];
+ created_at: string;
+ last_used_at?: string;
+ revoked_at?: string;
+ description?: string;
+}
+
+export interface CreateAPIKeyResponse {
+ api_key: APIKey;
+ plain_text_key: string;
+}
+
// Schedule types
export type Schedule = {
id: string;
@@ -345,3 +379,4 @@ export type ScheduleCreatable = {
export type ScheduleUpdateable = {
is_enabled: boolean;
};
+