Skip to main content
The Privileged Actions API lets your plugin request host-mediated operations that require elevated permissions: writing to /etc/hosts, mutating the filesystem within a declared scope, and executing scoped processes. All actions are validated before dispatch and travel through the host’s capability enforcement layer.

Import

import {
  // Request builders
  createHostsWriteActionRequest,
  createFilesystemMutateActionRequest,
  createProcessExecActionRequest,
  createWorkflowRunActionRequest,
  validatePrivilegedActionRequest,
  createFilesystemScopeCapability,
  createProcessScopeCapability,

  // Transport
  createPrivilegedActionBackendRequest,
  requestPrivilegedAction,

  // Response helpers
  createPrivilegedActionCorrelationId,
  isPrivilegedActionSuccessResponse,
  isPrivilegedActionErrorResponse,
  unwrapPrivilegedActionResponse,
} from "@anikitenko/fdo-sdk";

Types

HostsWriteActionRequest

type HostsWriteActionRequest = {
  action: "system.hosts.write";
  payload: {
    records: HostsRecord[];
    dryRun?: boolean;
    tag?: string;
  };
};

type HostsRecord = {
  address: string;
  hostname: string;
  comment?: string;
};

FilesystemMutateActionRequest

type FilesystemMutateActionRequest = {
  action: "system.fs.mutate";
  payload: {
    scope: string;
    operations: FilesystemMutationOperation[];
    dryRun?: boolean;
    reason?: string;
  };
};

FilesystemMutationOperation

All filesystem mutation operations are discriminated unions on type:
type FilesystemMutationOperation =
  | { type: "mkdir";      path: string; recursive?: boolean; mode?: number }
  | { type: "writeFile";  path: string; content: string; encoding?: "utf8" | "base64"; mode?: number }
  | { type: "appendFile"; path: string; content: string; encoding?: "utf8" | "base64" }
  | { type: "rename";     from: string; to: string }
  | { type: "remove";     path: string; recursive?: boolean; force?: boolean };

ProcessExecActionRequest

type ProcessExecActionRequest = {
  action: "system.process.exec";
  payload: {
    scope: string;
    command: string;
    args?: string[];
    cwd?: string;
    env?: Record<string, string>;
    timeoutMs?: number;
    input?: string;
    encoding?: "utf8" | "base64";
    dryRun?: boolean;
    reason?: string;
  };
};

PrivilegedActionSuccessResponse

type PrivilegedActionSuccessResponse<TResult = unknown> = {
  ok: true;
  correlationId: string;
  result?: TResult;
};

PrivilegedActionErrorResponse

type PrivilegedActionErrorResponse = {
  ok: false;
  correlationId: string;
  error: string;
  code?: string;
};

PrivilegedActionResponse

The discriminated union returned from all requestPrivilegedAction calls:
type PrivilegedActionResponse<TResult = unknown> =
  | PrivilegedActionSuccessResponse<TResult>
  | PrivilegedActionErrorResponse;

RequestPrivilegedActionOptions

type RequestPrivilegedActionOptions = {
  correlationId?: string;        // Provide a fixed correlation id
  handler?: string;              // Override the iframe bridge handler name
  correlationIdPrefix?: string;  // Prefix for auto-generated correlation ids
};

Capability helpers

createFilesystemScopeCapability

Builds a typed system.fs.scope.<id> capability string from a scope id. Normalizes the id and throws if it contains no alphanumeric characters.
createFilesystemScopeCapability(scopeId: string): `system.fs.scope.${string}`
createFilesystemScopeCapability("my-plugin-data");
// → "system.fs.scope.my-plugin-data"

createProcessScopeCapability

Builds a typed system.process.scope.<id> capability string.
createProcessScopeCapability(scopeId: string): `system.process.scope.${string}`
createProcessScopeCapability("kubectl");
// → "system.process.scope.kubectl"

Request builders

All builders validate the request structure before returning. They throw if the request is malformed.

createHostsWriteActionRequest

createHostsWriteActionRequest(
  request: HostsWriteActionRequest
): HostsWriteActionRequest
const req = createHostsWriteActionRequest({
  action: "system.hosts.write",
  payload: {
    records: [
      { address: "127.0.0.1", hostname: "myapp.local", comment: "local dev" },
    ],
    tag: "my-plugin",
  },
});

createFilesystemMutateActionRequest

createFilesystemMutateActionRequest(
  request: FilesystemMutateActionRequest
): FilesystemMutateActionRequest
const req = createFilesystemMutateActionRequest({
  action: "system.fs.mutate",
  payload: {
    scope: "my-plugin-data",
    operations: [
      { type: "mkdir",     path: "/tmp/my-plugin", recursive: true },
      { type: "writeFile", path: "/tmp/my-plugin/config.json", content: '{"key":"value"}' },
    ],
    reason: "Initialize plugin config directory",
  },
});

createProcessExecActionRequest

createProcessExecActionRequest(
  request: ProcessExecActionRequest
): ProcessExecActionRequest
const req = createProcessExecActionRequest({
  action: "system.process.exec",
  payload: {
    scope: "kubectl",
    command: "kubectl",
    args: ["get", "pods", "-n", "default", "-o", "json"],
    timeoutMs: 10000,
  },
});

createWorkflowRunActionRequest

createWorkflowRunActionRequest(
  request: ScopedWorkflowRunActionRequest
): ScopedWorkflowRunActionRequest
See Operator Tooling API for workflow types and examples.

validatePrivilegedActionRequest

Validates any privileged action request object. Returns the typed request or throws on invalid input.
validatePrivilegedActionRequest(request: unknown): HostPrivilegedActionRequest

Transport

createPrivilegedActionBackendRequest

Wraps a validated request in an envelope with a correlation id. Use this when you need the full PrivilegedActionBackendRequest envelope (e.g. for testing or custom transport).
createPrivilegedActionBackendRequest<TRequest extends HostPrivilegedActionRequest>(
  request: TRequest,
  options?: RequestPrivilegedActionOptions
): PrivilegedActionBackendRequest<TRequest>
const envelope = createPrivilegedActionBackendRequest(req, {
  correlationIdPrefix: "kubectl-query",
});
// { correlationId: "kubectl-query-1718000000000", request: { ... } }

requestPrivilegedAction

Dispatches a privileged action request through the plugin iframe bridge and returns the host response. This is the primary function you call to execute a privileged operation.
requestPrivilegedAction<TResult = unknown, TRequest extends HostPrivilegedActionRequest = HostPrivilegedActionRequest>(
  request: TRequest,
  options?: RequestPrivilegedActionOptions
): Promise<PrivilegedActionResponse<TResult>>
requestPrivilegedAction only works inside the FDO plugin iframe runtime. It throws immediately if called outside that context (e.g. in unit tests without a mock).
const response = await requestPrivilegedAction(req, {
  correlationIdPrefix: "kubectl-query",
});

if (isPrivilegedActionSuccessResponse(response)) {
  console.log(response.result);
} else {
  console.error(response.error);
}

Response helpers

createPrivilegedActionCorrelationId

Generates a time-stamped correlation id with an optional prefix.
createPrivilegedActionCorrelationId(prefix?: string): string
createPrivilegedActionCorrelationId("kubectl-query");
// → "kubectl-query-1718000000000"

isPrivilegedActionSuccessResponse

Type guard — returns true if response.ok === true and correlationId is a string.
isPrivilegedActionSuccessResponse<TResult = unknown>(value: unknown): value is PrivilegedActionSuccessResponse<TResult>

isPrivilegedActionErrorResponse

Type guard — returns true if response.ok === false, correlationId is a string, and error is a string.
isPrivilegedActionErrorResponse(value: unknown): value is PrivilegedActionErrorResponse

unwrapPrivilegedActionResponse

Returns response.result for a success response. For error responses, throws an Error with response.error as the message. If response.code is present, it is attached to the thrown error as .code.
unwrapPrivilegedActionResponse<TResult = unknown>(
  response: PrivilegedActionResponse<TResult>
): TResult | undefined
try {
  const result = unwrapPrivilegedActionResponse(response);
  // result is TResult | undefined on success
} catch (err) {
  // err is an Error; err.code may be set
}

End-to-end example: execute a scoped process

import {
  createProcessExecActionRequest,
  requestPrivilegedAction,
  isPrivilegedActionSuccessResponse,
  parseMissingCapabilityError,
} from "@anikitenko/fdo-sdk";

async function listKubernetesPods(): Promise<string> {
  const req = createProcessExecActionRequest({
    action: "system.process.exec",
    payload: {
      scope: "kubectl",
      command: "kubectl",
      args: ["get", "pods", "-n", "default", "-o", "json"],
      timeoutMs: 15000,
    },
  });

  try {
    const response = await requestPrivilegedAction(req, {
      correlationIdPrefix: "kubectl-pods",
    });

    if (isPrivilegedActionSuccessResponse(response)) {
      return JSON.stringify(response.result, null, 2);
    }
    return `Error: ${response.error}`;
  } catch (err) {
    const diag = parseMissingCapabilityError(err);
    if (diag) return `Missing capability: ${diag.label}. ${diag.remediation}`;
    throw err;
  }
}

End-to-end example: write to hosts file

import {
  createHostsWriteActionRequest,
  requestPrivilegedAction,
  unwrapPrivilegedActionResponse,
} from "@anikitenko/fdo-sdk";

async function addHostEntry() {
  const req = createHostsWriteActionRequest({
    action: "system.hosts.write",
    payload: {
      records: [{ address: "127.0.0.1", hostname: "myapp.local", comment: "added by my-plugin" }],
      tag: "my-plugin",
    },
  });

  const response = await requestPrivilegedAction(req);
  return unwrapPrivilegedActionResponse(response); // throws on error
}