oss

GitHub

提供S3兼容对象存储的CLI操作技能,支持通过命令语法列出、读取、上传、复制、移动、删除及生成预签名URL等文件管理任务。

internal/ai/skills/oss/SKILL.md opskat/opskat

Trigger Scenarios

需要列举或浏览存储桶/对象列表 需要从OSS下载或获取文件内容 需要向OSS上传或写入文件 需要在OSS中复制或移动对象 需要删除OSS中的对象 需要生成对象的临时访问链接

Install

npx skills add opskat/opskat --skill oss -g -y
More Options

Non-standard path

npx skills add https://github.com/opskat/opskat/tree/main/internal/ai/skills/oss -g -y

Use without installing

npx skills use opskat/opskat@oss

指定 Agent (Claude Code)

npx skills add opskat/opskat --skill oss -a claude-code -g -y

安装 repo 全部 skill

npx skills add opskat/opskat --all -g -y

预览 repo 内 skill

npx skills add opskat/opskat --list

SKILL.md

Frontmatter
{
    "name": "oss",
    "description": "List, read, upload, copy, move, delete and presign objects in S3-compatible object storage via exec, using a family + verb + target command syntax."
}

OSS assets

OSS assets connect to an S3-compatible object storage endpoint (AWS S3, MinIO, Aliyun OSS, …). The asset names the endpoint and credentials only — the bucket is part of every command's target, not part of the asset.

Command syntax

<family> <verb> [target] [--flags]family is bucket or object, verb is the operation, and target is <bucket>/<key> (no leading slash).

Every example below is literally executable as written. Optional flags are not marked with brackets; each useful combination is spelled out on its own line.

bucket

  • bucket list

object

  • object list backups
  • object list backups/2026/
  • object list backups/2026/ --max-keys=100
  • object list backups/2026/ --max-keys=100 --after=2026/03/db.sql.gz
  • object stat backups/2026/db.sql.gz
  • object get backups/app.conf (returns the content inline, truncated to 64 KiB)
  • object get backups/app.conf --max-bytes=4096
  • object get backups/2026/db.sql.gz --file=/tmp/db.sql.gz (streams to a local file instead)
  • object put backups/2026/db.sql.gz --file=/tmp/db.sql.gz
  • object put backups/app.conf --file=/tmp/app.conf --content-type=text/plain
  • object copy backups/2026/db.sql.gz --to=archive/db-2026.sql.gz
  • object move backups/2026/db.sql.gz --to=archive/db-2026.sql.gz
  • object delete backups/2026/old.log
  • object presign backups/2026/db.sql.gz
  • object presign backups/2026/db.sql.gz --expiry=600
  • object presign uploads/inbox/report.pdf --method=put --expiry=600 (denied by the default policy, see Notes)

Flag reference

Every flag each verb accepts — anything else is rejected rather than ignored. Bold flags are required: omitting one does not default it, the command is rejected before it runs. Verbs not listed here take no flags at all.

  • object list: --max-keys, --after
  • object get: --file, --max-bytes
  • object put: --file, --content-type
  • object copy: --to
  • object move: --to
  • object presign: --expiry, --method

Flag values

Checked before any approval dialog, so a wrong value costs nothing:

  • --max-keys, --max-bytes and --expiry must be plain decimal integers: 1000, not 1,000, 1_000, 1e3 or 3.0.
  • --method is get or put, lower case exactly. Nothing else is accepted, and there is no case folding: GET is an error rather than a synonym. Omitting it means get, so a bare object presign requests object.presign.read.
  • --expiry defaults to 3600 seconds when omitted.
  • --file must be an absolute local path. The approved command string is all that identifies the file, and a relative path resolves against a working directory that is not part of it, so it would land somewhere unpredictable.
  • --file and --max-bytes cannot be given together: they select two different behaviors of object get (stream the whole object to disk, or return the first bytes inline), so one of them would have to be ignored.
  • --max-bytes defaults to 64 KiB and is capped at 1 MiB. A larger value is reduced to the cap rather than rejected, and truncated then reports that the object was longer.
  • --max-keys is capped at 1000. A larger value is rejected, not reduced: silently returning fewer keys than asked would break --after pagination against what the caller expected to page through.
  • --expiry is capped at 604800 seconds (7 days) and is also rejected rather than reduced: a longer-lived presigned URL is what S3-compatible backends refuse to sign in the first place, so a value over the cap would otherwise be approved and then fail.
  • --to is a second <bucket>/<key> and follows the same rules as the target, including the requirement that it name a single object.

Not checked on this side at all — the storage service is the only thing that will reject a wrong value, after approval and a round trip:

  • --content-type is passed through verbatim as the object's MIME type; omitting it lets the service decide.
  • --after is a continuation cursor, not a filter: pass back the nextContinuationToken from the previous object list result to read the next page.

Results

  • bucket list returns {"buckets":[…]}.
  • object list returns the raw listing: prefixes (one level of "folders"), objects, plus isTruncated and nextContinuationToken for paging.
  • object stat returns the object's metadata.
  • object get without --file returns content together with encoding (utf-8, or base64 when the bytes are not valid UTF-8) and truncated. When truncated is true you read only the first bytes — re-run with --file rather than guessing at the rest.
  • object get --file returns the byte count, the object and the local file path; object put returns the byte count and the object (bucket/key), with no file. The content never passes through the conversation either way.
  • object copy, object move and object delete return {"status":"ok",…}.
  • object presign returns the signed url, its method and expiresIn seconds. The URL is fully usable; the audit log stores it with the signature parameters redacted.

Approval and policy rules

Approval is granted per <action> <resource>, where resource is <bucket>/<key>:

command permission(s) requested
bucket list bucket.list *
object list B/P object.list B/P
object stat B/K, object get B/K object.read B/K
object get B/K --file=P object.read B/K and a local-write check on P (the same gate cp uses when writing to this machine)
object put B/K object.write B/K
object copy S --to=D object.read S and object.write D
object move S --to=D object.read S, object.write D and object.delete S
object delete B/K object.delete B/K
object presign B/K --method=get object.presign.read B/K
object presign B/K --method=put object.presign.write B/K

copy and move request every one of their resources: any one of them being denied rejects the whole command, and where an allow list exists all of them must match.

Rules are written the same way, with * wildcards that do not cross / inside a key:

rule meaning
* everything
object.read mybucket or object.read mybucket/ every object in the bucket, at any depth
object.read mybucket/logs/ everything under the logs/ prefix, at any depth
object.read mybucket/logs/*.gz only *.gz directly under logs/
object.* mybucket/ any object operation on that bucket
object.presign.* * any presigned URL on any bucket

Notes

  • Presigned PUT URLs are denied by the default policy and cannot be enabled by an allow rule: a signed upload URL moves write access outside this app entirely — anyone holding it can write that key until it expires, with no further policy, approval or audit. Use object put instead — no asset or group policy change can enable it, because the deny is a floor merged into every effective policy.
  • Object keys may contain spaces; quote the whole target when they do, e.g. object stat 'mybucket/My Report.pdf'. Leading or trailing whitespace is rejected — permission rules split <action> <resource> at the first whitespace, so a padded name could never be authorized.
  • Every object verb takes exactly one target and it must name a real key: object stat mybucket is rejected, because mybucket as a rule would authorize the whole bucket rather than one object. object list is the exception — listing is always by prefix, so a bare bucket name is normalized to mybucket/.
  • A trailing / names the zero-byte "folder marker" object, so object delete mybucket/logs/ deletes exactly that marker. Because the same string read as a rule means the whole prefix, such an approval is never turned into a standing grant: repeating it asks again. object list is the exception — a listing approval on mybucket/logs/ does become a standing grant, because there the command and the rule cover the same range.
  • Targets must not start with / or --, and the bucket is part of the target rather than of the asset — there is no per-asset default bucket.
  • object copy and object move are single-object and server-side; both endpoints must be on this same asset. Use the cp tool to move data between different assets or between object storage and a server, and to copy whole prefixes.
  • Unknown flags are rejected rather than ignored, so a typo such as --max_keys=100 fails instead of silently listing the default page size.
  • The command line is shell-tokenized but never shell-executed: $, |, > and & produce an error rather than expanding or redirecting.
  • The scope parameter is not used by OSS assets; the target names bucket and key.

Asset config (for put_asset)

field type required notes
endpoint string yes Host, or scheme://host[:port]
access_key_id string yes
secret_access_key string no Stored encrypted; never echoed back
credential_id number no Reference to a managed credential instead of an inline secret_access_key; 0 means none
provider string no UI provider preset label (e.g. "s3", "minio"); does not change connection behavior
region string no
use_path_style bool no true to force path-style addressing (needed by most self-hosted S3-compatible services)
use_ssl bool no true to connect over HTTPS
connect_timeout number no Seconds; 0 uses the default

Example:

put_asset(name="backups-bucket", type="oss", config={"endpoint":"s3.us-east-1.amazonaws.com","region":"us-east-1","access_key_id":"AKIAEXAMPLE","secret_access_key":"...","use_ssl":"true"})

Version History

  • d6c7a6e Current 2026-08-16 07:29

    修正文档契约漂移:明确presign PUT受内置deny组限制,object list前缀审批机制,oss get --file需过本地写入门禁,presign默认method=get且expiry=3600,put返回无file字段等实现细节。

  • aeb4bc3 2026-07-24 16:28

Same Skill Collection

internal/ai/skills/database/SKILL.md
internal/ai/skills/etcd/SKILL.md
internal/ai/skills/k8s/SKILL.md
internal/ai/skills/kafka/SKILL.md
internal/ai/skills/local/SKILL.md
internal/ai/skills/mongodb/SKILL.md
internal/ai/skills/rdp/SKILL.md
internal/ai/skills/redis/SKILL.md
internal/ai/skills/serial/SKILL.md
internal/ai/skills/ssh/SKILL.md
internal/ai/skills/vnc/SKILL.md
plugin/opsctl/skills/opsctl/SKILL.md

Metadata

Files
0
Version
d6c7a6e
Hash
b880cbda
Indexed
2026-07-24 16:28

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-18 03:58
浙ICP备14020137号-1 $mapa de visitantes$