Skip to content
AsterDrive Developer DocsDeveloper

Admin API

The following paths are relative to /api/v1. Every endpoint on this page requires administrator privileges except the storage OAuth provider callback /admin/policies/storage-authorization/callback.

This page keeps the most important admin endpoint groups. For usage-oriented admin-console guidance, see Admin Console.

Most admin list endpoints already use offset pagination:

  • /admin/policies
  • /admin/policy-groups
  • /admin/remote-nodes
  • /admin/users
  • /admin/teams
  • /admin/teams/{id}/members
  • /admin/shares
  • /admin/tasks
  • /admin/files
  • /admin/file-blobs
  • /admin/config
  • /admin/locks
  • /admin/audit-logs

Default ordering varies by DTO. Common defaults:

  • users, teams, policies, policy groups, remote nodes, shares, audit logs: created_at desc
  • background tasks: updated_at desc
  • locks: id asc
  • team members: role asc
MethodPathDescription
GET/admin/overviewRead aggregated admin dashboard data
GET/admin/system-infoRead authenticated version and build time

The overview response includes user, file, blob, share, audit, and task summaries plus recent activity. Query parameters include days, timezone, and event_limit.

GET /admin/system-info returns { "version": "...", "build_time": "..." }. Build fingerprints are exposed only through this authenticated admin route; anonymous /health reports service status without version or build details.

MethodPathDescription
GET/admin/policiesList storage policies
POST/admin/policiesCreate storage policy
GET/admin/policies/{id}Read policy details
GET/admin/policies/{id}/capacityRead policy capacity observation
PATCH/admin/policies/{id}Update policy
DELETE/admin/policies/{id}Delete policy
GET/admin/policies/storage-driversList storage connector descriptors
GET/admin/policies/storage-credential-providersList storage OAuth credential providers
POST/admin/policies/{id}/testTest saved policy
POST/admin/policies/{id}/actionExecute a storage action for a saved policy
POST/admin/policies/{id}/promote-s3-driverPromote a generic S3-compatible policy to a supported specialized driver
POST/admin/policies/{id}/storage-authorization/startStart storage OAuth authorization for a policy
GET/admin/policies/{id}/storage-credentialsList stored OAuth credentials for a policy
POST/admin/policies/{id}/storage-credentials/{provider}/validateValidate a stored OAuth credential
GET/admin/policies/storage-authorization/callbackStorage OAuth provider callback entry; does not require an admin JWT and redirects back to the admin UI
POST/admin/policies/testTest connection with draft parameters
POST/admin/policies/actionExecute a storage action with draft policy parameters

Create example:

{
"name": "archive-s3",
"driver_type": "s3",
"endpoint": "https://s3.example.com",
"bucket": "archive",
"access_key": "AKIA...",
"secret_key": "...",
"base_path": "asterdrive/",
"max_file_size": 10737418240,
"chunk_size": 10485760,
"is_default": false
}

Current notes:

  • driver_type currently supports local, s3, sftp, azure_blob, tencent_cos, remote, and one_drive
  • GET /admin/policies/storage-drivers returns StorageConnectorDescriptor entries. The frontend should use descriptor capabilities, fields, upload_workflows, actions, and credential_mode to decide forms, connection tests, upload/download strategies, and action affordances instead of maintaining a hard-coded driver capability matrix.
  • create and update both honor request chunk_size
  • options carries policy-level behavior:
    • S3-compatible / Azure Blob / Tencent COS object-storage connectors use object_storage_upload_strategy / object_storage_download_strategy for transfer strategy. Legacy s3_upload_strategy / s3_download_strategy JSON remains accepted as a compatibility alias.
    • Remote upload and download strategies through remote_upload_strategy / remote_download_strategy
    • local content_dedup
    • generic S3 path-style addressing through s3_path_style (defaults to true)
    • S3 connect / read / operation timeouts
    • storage-native thumbnails / image previews with storage_native_processing_enabled, thumbnail_processor, and thumbnail_extensions
    • storage-native media metadata with storage_native_media_metadata_enabled and media_metadata_extensions
    • OneDrive location options: onedrive_account_mode, onedrive_tenant, onedrive_site_id, onedrive_drive_id, onedrive_group_id, and onedrive_root_item_id
    • OneDrive large-upload strategy through provider_resumable_upload_strategy: server_relay (default) or frontend_direct
    • OneDrive download strategy through provider_download_strategy: server_relay (default) or frontend_direct
    • OneDrive download filename semantics through provider_download_filename_mode: provider_native (default) or strict_current
    • SFTP host key pinning: sftp_host_key_fingerprint
  • application_config.microsoft_graph stores OneDrive / Microsoft Graph app settings. Client secrets are stored encrypted; API responses expose only client_secret_configured.
  • driver_type = "azure_blob" uses Azure Block Blob capabilities. Presigned browser upload uses SAS URLs and requires the client to send x-ms-blob-type: BlockBlob.
  • driver_type = "one_drive" uses Microsoft Graph OAuth credentials. Save the policy and application_config.microsoft_graph before starting authorization.
  • driver_type = "sftp" uses SSH username / password credentials to connect to an SFTP server. Endpoint supports sftp://host:port, bare host, and host:port; the remote root belongs in base_path. Unknown or mismatched SSH host keys are rejected as StorageErrorKind::Precondition with diagnostics that include actual / expected fingerprints; the confirmed fingerprint is stored in options.sftp_host_key_fingerprint.
  • driver_type = "tencent_cos" uses the S3-compatible object path for normal reads and writes, validates Tencent COS endpoint shape, and can expose COS CI storage-native thumbnail / image-preview / media-metadata capabilities when the policy opts in
  • built-in Local, S3-compatible, SFTP, Azure Blob, OneDrive, and Remote drivers do not expose storage-native thumbnail, image-preview, or media-metadata capabilities
  • legacy {"presigned_upload":true} remains compatible with object-storage presigned upload
  • allowed_types can be managed through REST
  • Creating a driver_type = "remote" policy requires both remote_node_id and remote_storage_target_key. The target must belong to that node’s current binding, have no last_error, and satisfy applied_revision >= desired_revision.
  • After a node is selected, the policy create/edit UI loads its target list and driver descriptors. An admin can quick-create a target in the same flow, after which the new target is selected automatically. Fields and capabilities remain backend-descriptor driven.
  • A legacy remote policy with an empty target key may retain it only when an edit does not change the remote binding; runtime access then falls back to the follower binding’s default target. New policies and remote-binding changes require an explicit target key.
  • PATCH cannot change driver_type
  • POST /admin/policies/{id}/promote-s3-driver currently supports promoting a generic s3 policy to tencent_cos. The body must include the target driver and current endpoint / bucket, for example { "target_driver_type": "tencent_cos", "endpoint": "https://bucket-1250000000.cos.ap-guangzhou.myqcloud.com", "bucket": "bucket-1250000000" }. Promotion is rejected unless the bucket stays unchanged, there are no active upload sessions for the policy, and the target driver validates the endpoint / bucket combination.
  • GET /admin/policies supports limit, offset, sort_by, sort_order
  • GET /admin/policies/{id}/capacity returns StoragePolicyCapacityInfo; local returns filesystem capacity, S3-compatible and Azure Blob are explicitly unsupported, OneDrive reads Microsoft Graph drive quota, and remote forwards follower capacity status
  • DELETE /admin/policies/{id}?force=true only cleans upload sessions that still reference the policy. Existing blobs or policy-group references still block deletion. If temp objects or multipart uploads need delayed cleanup, a storage_policy_temp_cleanup task is created.

POST /admin/policies/{id}/test and POST /admin/policies/test return an ordinary empty success response on success:

{
"code": "success",
"msg": "",
"data": {}
}

Failed connection tests no longer return a StoragePolicyProbeResult success payload. They use the standard error response and expose redacted diagnostics through error.diagnostic:

{
"code": "storage.auth_failed",
"msg": "storage authentication failed",
"error": {
"retryable": false,
"diagnostic": {
"kind": "auth",
"message": "credentials were rejected by the storage provider"
}
}
}

Draft test requests support optional policy_id. While editing a saved policy, blank sensitive fields such as access_key or secret_key can be filled from the saved policy by S3-compatible, SFTP, Azure Blob, and Tencent COS connectors. Unsaved new policies must still provide complete credentials.

These endpoints currently mainly serve the OneDrive / Microsoft Graph connector:

  • GET /admin/policies/storage-credential-providers lists providers. microsoft_graph is currently supported; google_drive is reserved with supported = false.
  • Creating or updating a OneDrive policy first saves Microsoft Graph app settings through application_config.microsoft_graph; client secrets are encrypted at rest.
  • POST /admin/policies/{id}/storage-authorization/start only needs the provider; the backend reuses saved application config to start authorization.
  • After successful authorization, the callback writes storage_policy_credentials and redirects to /admin/policies?storage_authorization=success&policy_id=.... The callback does not require an admin JWT because Microsoft Graph and similar providers return to it through the browser.
  • GET /admin/policies/{id}/storage-credentials returns credential status, tenant, account label, scopes, expiry, and refresh timestamps, but never access or refresh tokens.
  • POST /admin/policies/{id}/storage-credentials/{provider}/validate validates the stored credential and updates status to authorized, reauth_required, permission_denied, or invalid.

Start authorization example:

POST /api/v1/admin/policies/12/storage-authorization/start
{
"provider": "microsoft_graph"
}

The returned authorization_url is meant for browser navigation:

{
"code": "success",
"msg": "",
"data": {
"authorization_url": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?...",
"expires_in": 300,
"provider": "microsoft_graph",
"microsoft_graph": {
"cloud": "global",
"tenant": "common",
"client_id": "00000000-0000-0000-0000-000000000000",
"client_secret_configured": true,
"scopes": ["offline_access", "Files.ReadWrite.All", "Sites.ReadWrite.All"]
}
}
}

Storage policy actions are the unified entry point for optional management capabilities exposed by storage drivers. Default built-in capabilities should extend the StoragePolicyActionType enum instead of adding provider-specific HTTP routes. Future plugin capabilities may expose their own schema route for parameter discovery, but execution should still stay action-oriented where possible.

Current actions:

actionSupported driverMutates remote stateDescription
configure_tencent_cos_corstencent_cosyesConfigure Tencent COS bucket CORS from public_site_url

Saved policy request:

POST /api/v1/admin/policies/12/action
{
"action": "configure_tencent_cos_cors"
}

Draft policy request:

POST /api/v1/admin/policies/action
{
"action": "configure_tencent_cos_cors",
"policy_id": 12,
"driver_type": "tencent_cos",
"endpoint": "https://bucket-1250000000.cos.ap-guangzhou.myqcloud.com",
"bucket": "bucket-1250000000",
"access_key": "AKID...",
"secret_key": "...",
"base_path": "prod/"
}

configure_tencent_cos_cors behavior:

  • request bodies do not accept allowed_origin or allowed_origins
  • draft request connection fields are flat fields, not nested under a policy object
  • policy_id is optional and is only used for draft actions while editing a saved policy; if access_key or secret_key is blank, the backend fills that blank credential field from the saved policy
  • without policy_id, draft actions must carry complete credentials themselves; this covers unsaved new policies and purely transient parameter tests
  • the backend reads all origins from runtime config public_site_url and writes them as multiple AllowedOrigin entries in one COS CORS rule
  • if public_site_url is empty, the action returns policy.action_parameter_required
  • if the policy is not tencent_cos, the action returns policy.action_unsupported
  • AsterDrive uses the stable rule id asterdrive-presigned-access
  • Tencent COS does not provide an atomic append-CORS-rule API; AsterDrive reads current rules with GET Bucket cors, preserves unrelated rules, replaces the rule with the same ID, and writes the full document back with PUT Bucket cors
  • PUT Bucket cors requires Content-MD5; the server calculates the MD5 of the XML body and includes it in the COS signature
  • successful execution writes admin audit action admin_trigger_storage_action; details include action, driver_type, used_draft_values, and mutates_remote_state

Success response example:

{
"code": "success",
"msg": "",
"data": {
"action": "configure_tencent_cos_cors",
"tencent_cos_cors": {
"rule_id": "asterdrive-presigned-access",
"allowed_origins": [
"https://drive.example.com",
"https://panel.example.com"
],
"request_id": "NmEy...",
"preserved_rule_count": 1,
"replaced_existing_rule": true,
"response_vary": true
}
}
}

Common error codes:

CodeMeaning
policy.action_unsupportedThe action does not support this policy or driver type
policy.action_parameter_requiredRequired backend configuration is missing, such as an empty public_site_url
policy.action_parameter_invalidAction parameters or backend-derived parameters are invalid
storage.auth_failedCOS credentials are wrong or signing failed
storage.permission_denied / storage.permissionCOS CAM permissions are insufficient, for example missing name/cos:PutBucketCORS
storage.misconfiguredCOS reports a configuration error, such as bad bucket, endpoint, required headers, or XML
storage.transient_failure / storage.transientCOS or network failure that may be retried later

Admins can create and resume cross-policy blob migration tasks.

MethodPathDescription
POST/admin/storage-migrationsCreate storage-policy migration task
POST/admin/storage-migrations/dry-runPreflight migration plan without creating a task
POST/admin/storage-migrations/{task_id}/resumeResume existing migration task

Create request:

{
"source_policy_id": 1,
"target_policy_id": 2,
"delete_source_after_success": false
}

Rules:

  • source and target policy IDs must be positive and different
  • delete_source_after_success = true is currently rejected
  • dry-run checks target stream-upload support and performs a write/delete probe
  • capacity checks use the bytes still expected to be copied, not the whole source policy size
  • insufficient capacity blocks task creation; unsupported and unavailable become warnings
  • opaque key conflicts are counted and resolved by writing migrated blobs under new migration-... keys
  • task kind is BackgroundTaskKind::StoragePolicyMigration
  • migration tasks have independent checkpoints and resume support
  • content SHA-256 blobs can be merged across policies only when hash is 64-hex and size also matches
  • opaque blobs are never merged across policies

Remote nodes are follower storage nodes managed by the primary, mainly for driver_type = "remote" policies.

MethodPathDescription
GET/admin/remote-nodesPaginated managed follower nodes
POST/admin/remote-nodesCreate remote-node record
GET/admin/remote-nodes/{id}Read remote-node details
PATCH/admin/remote-nodes/{id}Update name, base URL, transport mode, or enabled state
DELETE/admin/remote-nodes/{id}Delete remote node; rejected while referenced by policies
POST/admin/remote-nodes/{id}/testTest saved remote-node connection
POST/admin/remote-nodes/testTest draft remote-node connection
POST/admin/remote-nodes/{id}/enrollment-tokenGenerate follower enrollment command
GET/admin/remote-nodes/{id}/storage-target-driversList follower remote storage target driver descriptors
GET/admin/remote-nodes/{id}/storage-targetsList follower remote storage targets
POST/admin/remote-nodes/{id}/storage-targetsCreate follower remote storage target
PATCH/admin/remote-nodes/{id}/storage-targets/{target_key}Update follower remote storage target
DELETE/admin/remote-nodes/{id}/storage-targets/{target_key}Delete follower remote storage target

Version 0.4.0 removed the legacy /ingress-profile-drivers and /ingress-profiles compatibility paths. Clients must use /storage-target-drivers and /storage-targets; DTO field names use target_key.

Create example:

{
"name": "edge-sh-01",
"base_url": "",
"transport_mode": "auto",
"is_enabled": true
}

Notes:

  • transport_mode supports direct, reverse_tunnel, and auto
  • direct requires a primary-reachable base_url
  • reverse_tunnel requires the follower to actively connect back to /api/v1/internal/remote-tunnel/*
  • auto uses direct when base_url is non-empty and reverse tunnel otherwise
  • empty base_url usually means the enrollment flow will complete binding later
  • remote-node details include transport_mode, enrollment_status, last_error, capabilities, last_checked_at, and tunnel
  • reverse tunnel cannot be combined with remote browser presigned upload / download strategies
  • remote storage target request bodies match the follower internal storage protocol; see Internal storage protocol

External auth providers are configured by admins. Anonymous login reads only enabled public summaries. Supported provider kinds are oidc, generic_oauth2, github, qq, google, and microsoft.

MethodPathDescription
GET/admin/external-auth/provider-kindsList supported provider kinds
GET/admin/external-auth/providersPaginated providers
POST/admin/external-auth/providersCreate provider
POST/admin/external-auth/providers/testTest draft provider config
GET/admin/external-auth/providers/{id}Read provider details
PATCH/admin/external-auth/providers/{id}Update provider
DELETE/admin/external-auth/providers/{id}Delete provider
POST/admin/external-auth/providers/{id}/testTest saved provider

OIDC example:

{
"provider_kind": "oidc",
"display_name": "Corp SSO",
"icon_url": "/static/external-auth/corp.svg",
"issuer_url": "https://idp.example.com",
"client_id": "asterdrive",
"client_secret": "secret",
"scopes": "openid email profile",
"enabled": true,
"auto_provision_enabled": true,
"auto_link_verified_email_enabled": true,
"require_email_verified": true,
"allowed_domains": ["example.com"]
}

Generic OAuth2 example:

{
"provider_kind": "generic_oauth2",
"display_name": "Logto",
"icon_url": "/static/external-auth/oauth-logo.svg",
"issuer_url": "https://id.example.com",
"authorization_url": "https://id.example.com/oidc/auth",
"token_url": "https://id.example.com/oidc/token",
"userinfo_url": "https://id.example.com/oidc/me",
"client_id": "asterdrive",
"client_secret": "secret",
"scopes": "openid email profile",
"enabled": true,
"auto_provision_enabled": false,
"auto_link_verified_email_enabled": false,
"require_email_verified": true
}

Microsoft example:

{
"provider_kind": "microsoft",
"display_name": "Microsoft",
"icon_url": "/static/external-auth/microsoft-logo.svg",
"options": {
"microsoft": {
"tenant": "organizations"
}
},
"client_id": "00000000-0000-0000-0000-000000000000",
"client_secret": "secret-value",
"scopes": "openid profile email",
"enabled": true,
"auto_provision_enabled": false,
"auto_link_verified_email_enabled": false,
"require_email_verified": false
}

Implementation notes:

  • provider key is generated by the server and used in /auth/external-auth/{kind}/{provider}/start
  • URLs must be HTTPS except localhost; fragments are not allowed
  • oidc supports discovery; generic_oauth2 uses manual authorization / token / userinfo endpoints
  • github, qq, google, and microsoft are dedicated provider kinds; endpoints and default claim semantics are fixed by backend drivers, so unsupported manual endpoint fields should not be sent
  • microsoft tenant configuration uses options.microsoft.tenant, which accepts common, organizations, consumers, or a concrete tenant UUID; provider details return normalized options
  • options is currently used for provider-specific configuration; options.microsoft is rejected for non-Microsoft providers
  • provider capabilities and field requirements come from GET /admin/external-auth/provider-kinds
  • client_secret is redacted as ***REDACTED*** when reading details, and client_secret_configured reports whether a saved secret exists
  • auto-provisioning can create local users, with optional email-domain restrictions
  • verified-email auto-linking can bind external identities to existing local users
  • when require_email_verified is enabled, unverified external emails go through /auth/external-auth/email-verification/*
  • dedicated provider behavior is documented in External Authentication Module
  • create, update, delete, and test write admin audit logs

These endpoints are admin-side observability and maintenance surfaces, not business file APIs.

MethodPathDescription
GET/admin/filesInspect file records, owning blobs, and version summaries
GET/admin/files/{id}Inspect one file and its versions
GET/admin/file-blobsInspect blob records, hash kinds, and reference counts
GET/admin/file-blobs/{id}Inspect one blob’s file and version references
POST/admin/file-blobs/maintenanceCreate maintenance task for selected blobs
PUT/admin/folders/{id}/policySet or clear an explicit folder policy across personal / team scopes

Filters:

  • /admin/files: name, blob_id, policy_id, owner_user_id, team_id, deleted, limit, offset, sort_by, sort_order
  • /admin/file-blobs: hash, policy_id, storage_path, ref_count_min, ref_count_max, size_min, size_max, limit, offset, sort_by, sort_order

hash_kind is derived for observability: 64-hex SHA-256 is content_sha256, everything else is opaque.

Maintenance request:

{
"action": "ref_count_reconcile",
"blob_ids": [1, 2, 3]
}

Supported actions:

  • integrity_check: check object existence and size only
  • ref_count_reconcile: recompute and fix ref_count
  • orphan_cleanup: recompute references, then clean blobs whose actual references and ref_count are both zero

The admin folder-policy request is { "policy_id": 12 }; { "policy_id": null } clears the explicit folder policy. A non-null ID must be positive and identify a policy eligible for folder binding. Locked or trashed folders reject the change. Success returns the updated FolderInfo, records a folder_policy_change audit event, and publishes a storage change event.

MethodPathDescription
GET/admin/policy-groupsList storage policy groups
POST/admin/policy-groupsCreate policy group
GET/admin/policy-groups/{id}Read policy group details
PATCH/admin/policy-groups/{id}Update policy group
DELETE/admin/policy-groups/{id}Delete policy group
POST/admin/policy-groups/{id}/migrate-assignmentsMigrate user and team policy group bindings by updating policy_group_id

Policy groups define storage policy selection for users and teams. They are rejected from deletion while still referenced. Migration responses report affected_users, affected_teams, and migrated_assignments.

MethodPathDescription
GET/admin/usersPaginated users
POST/admin/usersCreate user
GET/admin/users/{id}Read user details
PATCH/admin/users/{id}Update user profile, role, status, quota, policy group, or forced password-change flag
PUT/admin/users/{id}/passwordReset a user’s password
DELETE/admin/users/{id}/mfaClear a user’s MFA setup and revoke sessions
POST/admin/users/{id}/sessions/revokeRevoke all existing sessions for the user
DELETE/admin/users/{id}Delete user
GET/admin/users/{id}/avatar/{size}Read uploaded user avatar
POST/admin/users/invitationsCreate user invitation
GET/admin/users/invitationsPaginated user invitations
POST/admin/users/invitations/{id}/revokeRevoke a pending invitation

User lists support keyword / role / status style filtering and offset pagination. Avatar responses are raw binary and are not wrapped JSON.

POST /admin/users accepts an optional password and optional must_change_password. When password is omitted or blank, the server generates a 24-character temporary password, sets must_change_password = true, and returns the generated value once in generated_password. When a password is provided, must_change_password defaults to false unless the request explicitly sets it.

Invitation creation accepts { "email": "new-user@example.com" } and returns 201. Any existing pending invitation for the same email is revoked before the new pending record is created, and invitation mail is queued through the outbox. The create response may include the one-time invitation_url; list responses do not expose that token URL again. Lists use limit / offset, statuses are pending, accepted, expired, and revoked, and only pending invitations can be revoked.

PATCH /admin/users/{id} accepts must_change_password: true | false. Setting it to true requires the user to change their password after the next successful login; setting it to false clears the requirement before the user completes that flow. Any change to this flag increments session_version, deletes existing refresh sessions, invalidates the auth snapshot cache, and records admin_update_user audit details including the new must_change_password value.

While the flag is set, successful password, MFA, passkey, and external-auth login completions return:

{
"code": "success",
"msg": "",
"data": {
"status": "password_change_required",
"expires_in": 900
}
}

The issued access token is scoped to password change only. It can call GET /auth/me, PUT /auth/password, and POST /auth/logout; other authenticated routes return 403 with auth.password_change_required. POST /auth/refresh is also rejected while the flag or password-change token scope is present. PUT /auth/password still requires the current password and clears must_change_password after a successful update. The current password is temporary only when an administrator has reset the user’s password; if an administrator only sets must_change_password, the user’s existing password remains the current password.

MethodPathDescription
GET/admin/teamsPaginated teams
POST/admin/teamsCreate team and assign initial admin
GET/admin/teams/{id}Read team details
PATCH/admin/teams/{id}Update team
DELETE/admin/teams/{id}Archive a team
POST/admin/teams/{id}/restoreRestore an archived team
GET/admin/teams/{id}/audit-logsRead team audit logs
GET/admin/teams/{id}/membersPaginated team members
POST/admin/teams/{id}/membersAdd team member
PATCH/admin/teams/{id}/members/{member_user_id}Update member role
DELETE/admin/teams/{id}/members/{member_user_id}Remove team member

Admin team creation can create a team for another user and give that user the initial team-admin role. User-side POST /teams is more restrictive.

MethodPathDescription
GET/admin/sharesPaginated share audit / management list
DELETE/admin/shares/{id}Delete share
GET/admin/tasksPaginated all background tasks
POST/admin/tasks/cleanupDelete finished task records matching filters
GET/admin/configList runtime config entries
GET/admin/config/schemaRead system config schema
GET/admin/config/template-variablesRead template variable catalog
GET/admin/config/{key}Read one runtime config entry
PUT/admin/config/{key}Set runtime config entry
DELETE/admin/config/{key}Delete custom runtime config entry
POST/admin/config/{key}/actionExecute a config action for supported keys
GET/admin/locksPaginated lock list
DELETE/admin/locks/{id}Release a lock
DELETE/admin/locks/expiredDelete expired locks
GET/admin/audit-logsPaginated audit logs

Runtime config entries defined by the system cannot be deleted; custom entries can. The single source of truth for system config definitions is src/config/definitions.rs.

Archive and WebDAV operational keys include:

  • archive_compress_enabled defaults to true and gates /batch/archive-compress; disabling it returns archive_compress.disabled.
  • archive_download_user_enabled defaults to true and gates creation and consumption of personal/team ZIP download tickets; disabling it returns archive_download.user_disabled.
  • archive_download_share_enabled defaults to true and gates creation and consumption of public-share ZIP download tickets; disabling it returns archive_download.share_disabled.
  • webdav_max_active_locks_per_user defaults to 1024; new LOCK requests are rejected after the user reaches that ceiling.
  • webdav_download_audit_coalesce_window_secs defaults to 30 seconds and coalesces repeated WebDAV download audit records for the same account, file, request type, and client fingerprint. Set it to 0 to record every read.

Media-derivative limits are regular runtime config entries. thumbnail_max_source_bytes bounds which original files are accepted for thumbnail generation, while thumbnail_max_dimension and image_preview_max_dimension bound the rendered longest edge for list thumbnails and preview-panel images. Changing a dimension creates a dimension-specific derivative cache namespace instead of rewriting another configured size.

Custom runtime config entries also have a visibility field:

VisibilityBehavior
privateAdmin-only; never returned by /api/v1/public/custom-config
publicReadable without login
authenticatedReturned only when the request carries a valid access token

The field only applies to source = "custom" entries. Built-in system configuration cannot be made public through it. When omitted, new custom entries default to private.

GET /admin/config now includes visibility in addition to id, key, value, source, namespace, updated_at, and updated_by. Sensitive values are still redacted as ***REDACTED***.

The frontend custom-configuration read path is documented in Public API under GET /public/custom-config. That endpoint only returns the key/value map visible to the current request identity and does not expose admin-only fields.

Admin task APIs can see system tasks and blob-level cache tasks that ordinary users normally cannot see.

Link import is controlled by the offline_download_* runtime config keys. offline_download_engine_registry_json is the current structured engine registry: it contains ordered builtin and aria2 engine entries with enabled flags. Enabled engines are tried in registry order; if all engines are disabled, link import is disabled. The older offline_download_engine single-value key remains as a compatibility fallback when the registry is absent or invalid. offline_download_temp_dir is the staging root for link-import tasks. When blank, AsterDrive uses the default server temp directory. When set, it must be the same absolute path visible to both AsterDrive and any external downloader such as aria2.

File size, per-task speed, concurrency, and request timeout apply to all engines. When the aria2 registry entry is enabled, the aria2 RPC URL, RPC secret, RPC timeout, split, per-server connection count, and low-speed limit keys configure the administrator-managed aria2 JSON-RPC daemon. AsterDrive does not pass through arbitrary aria2 options, and the per-task speed limit maps to aria2 max-download-limit, not a daemon-wide limit. Admins can execute test_aria2_rpc against offline_download_engine_registry_json; the server probes aria2 with aria2.getVersion. Config actions may include unsaved form drafts in value and draft_values, so the aria2 probe can test the current registry, RPC URL, secret, and timeout before saving. Wrong RPC secrets return code = "offline_download.aria2_rpc_auth_failed"; other probe failures return code = "offline_download.aria2_rpc_probe_failed" instead of storage-driver error codes. Operational setup, temporary-directory semantics, and troubleshooting live in Offline Download.

When aria2 is enabled, AsterDrive still validates the HTTP/HTTPS source URL before dispatching the task, but the aria2 daemon performs its own DNS resolution and outbound connection. Operators should isolate the daemon at the network layer and restrict the JSON-RPC endpoint to AsterDrive.

  • Admin endpoints are intentionally grouped around operational ownership: storage, users, teams, shares, tasks, config, locks, audit, and observability.
  • Many admin actions write audit logs.
  • For storage behavior involving remote followers, read this page together with Internal storage protocol.
  • For user-facing file semantics, read Files, Folders, and Teams instead of treating admin observability endpoints as business APIs.