Skip to main content
Guyun
Language 简体 繁體 English

Alibaba Cloud OSS: mainland China with a filed domain

This is the most demanding route: bring your own domain, complete an ICP filing (usually 1–20 working days) and give the domain an HTTPS certificate; after that the console work takes about 10 minutes.

This is the official Guyun guide. If the console appears in another language, match the buttons by meaning.

Step by step

  1. Step 1

    Register and verify your identity

    • Register an account and complete identity verification when the console asks; skip this if you already have one.
    • Two separate sign-up entries, and the accounts do not carry over: the international site www.alibabacloud.com (mostly English; international card or PayPal) and the China site www.aliyun.com (Simplified Chinese; real-name verification, Alipay or WeChat Pay). Use the console of whichever site you registered on for the rest of this guide.
  2. Step 2

    Activate OSS

    • Search the console for Object Storage Service and choose Activate.
    • Tick the agreement before confirming; activation itself is free.
  3. Step 3

    Get a domain and complete the ICP filing

    • A domain bought from an overseas registrar (GoDaddy, Namecheap and the like) has to move to a registrar inside mainland China before it can be filed.
    • OSS does not supply filing service codes. Buy an eligible mainland server first (ECS or Simple Application Server, yearly/monthly for at least 3 months, with public bandwidth), take the code from it and file; review usually takes 1–20 working days.
  4. Step 4

    Create a bucket

    • Open the bucket list and choose Create bucket; enter a globally unique name such as your-bucket-name and pick a mainland region.
    • Set access to private and leave block public access on.
  5. Step 5

    Bind your domain, a certificate and a CNAME

    • Open the bucket's domain management, bind your domain, then select an HTTPS certificate under certificate hosting.
    • Order matters: add the domain in OSS first and let OSS add the DNS record for you; the CNAME must point straight at OSS, with CDN turned off — the three points that bite are under “Other cases” at the end of this page.
  6. Step 6

    Create a RAM user and get its key

    • Open Access Control (RAM) → Users → Create user and tick OpenAPI (programmatic) access; do not enable console logon.
    • The AccessKey ID and secret are shown once; copy both now, and never use the root account key.
  7. Step 7

    Attach the least-privilege policy to that user

    • Create a custom policy under Permissions → Policies, switch to the script (JSON) editor, paste the policy below and replace your-bucket-name with your real bucket name.
    • Open the user again and attach that policy to it.
  8. Step 8

    Enter the values in Guyun and test

    • In Guyun's Add storage screen choose Alibaba Cloud OSS, pick the place, then enter the name, bucket name and key — the HTTPS endpoint is your domain, e.g. https://oss.example.com. The app visits it as a custom domain and will not prefix the bucket name to the host — then choose Test connection & save.

Least-privilege policy (required)

Create a custom policy in RAM, switch to the script editor and paste this JSON.

json
{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["oss:ListObjects", "oss:GetBucketLocation", "oss:ListMultipartUploads"],
      "Resource": ["acs:oss:*:*:your-bucket-name"]
    },
    {
      "Effect": "Allow",
      "Action": ["oss:GetObject", "oss:PutObject", "oss:DeleteObject", "oss:AbortMultipartUpload", "oss:ListParts", "oss:RestoreObject"],
      "Resource": ["acs:oss:*:*:your-bucket-name/*"]
    }
  ]
}

Replace your-bucket-name with your real bucket name. Do not narrow the resource range to one folder either: Guyun writes the trash manifest and device records under the .guyun/ prefix. Multipart uploads (initiate / upload part / complete) are all covered by oss:PutObject, so they need no extra permission; oss:RestoreObject only restores objects that are already in this bucket, and costs nothing unless it is called.

Other cases (skip if not needed)

Why a custom domain is mandatory

Since 2025-03-20, an account that newly activated OSS cannot reach the data APIs (upload, download) of a mainland bucket through the default public endpoint; the request is refused with PublicEndpointForbidden.

What it restricts is the domain, not permissions: a private bucket, no public links at all, or even the S3-compatible domain all make no difference.

The test is when the account activated OSS, not when the bucket was created; buckets an older account creates later are exempt.

Binding your own domain: three things testing taught us

  1. The domain must CNAME straight to OSS. If the same bucket already has a domain that goes through Alibaba Cloud CDN (CNAME pointing at *.w.kunlunaq.com, certificate configured in the CDN console), that domain cannot be the endpoint — connecting Guyun with it failed in testing. A domain used as the endpoint must CNAME straight to OSS, with CDN turned off. The bucket's domain management shows this at a glance: a CDN-enabled row says Alibaba Cloud CDN acceleration: configured. The certificate has to live on the matching side too.
  2. Order: add the domain in OSS first and let OSS add the DNS record. The other way round (add the CNAME at your DNS provider first, then ask OSS to add it) fails with “record already exists” and looks like a broken setup. If you really must add it by hand, do not press the automatic button afterwards.
  3. The certificate lives in OSS certificate hosting. Path: OSS console → the bucket → Bucket configuration → Domain management → your domain → certificate hosting → select certificate → upload. The certificate must already exist in Certificate Management Service (CAS): bought from Alibaba Cloud it is simply in the list; a third-party certificate has to be uploaded to CAS first (public key + private key), or it will not appear in the dropdown. The certificate must cover the domain you entered.

Two details that catch people out

The CNAME target OSS gives you looks like <bucket>.<region>.taihangtop.cn (in testing, airdiode-upload.cn-beijing.taihangtop.cn), not the familiar <bucket>.oss-<region>.aliyuncs.com. Follow whatever the console shows; both point at OSS.

A domain can be bound to only one bucket at a time, and a host name can have only one CNAME: leave your existing CDN domain alone and use a fresh subdomain (e.g. guyun.godar.cn). Renewing the certificate in the same place does not disturb the bound CNAME or the bucket.

How to tell the chain works

  1. In OSS, use Copy file URL on any file with the custom domain selected and open it in a browser: look for the HTTPS padlock.
  2. Back in Guyun: Add storage → Alibaba Cloud OSS → place Beijing → bucket name → HTTPS endpoint https://guyun.godar.cn → key → Test connection & save. If it passes, the chain works.
  3. This exact path passed a real test on 2026-09-28 (bucket airdiode-upload with endpoint https://guyun.godar.cn, certificate in OSS certificate hosting, CDN off).

Filing service codes

  • OSS is not on the list of products that hand out filing service codes, so it cannot supply one.
  • To file a domain for OSS you first buy an eligible mainland server — ECS or Simple Application Server, billed yearly/monthly for at least 3 months, with public bandwidth. Free trials and pay-as-you-go ECS do not qualify.
  • Review usually takes 1–20 working days.
  • If your main domain is already filed, use a subdomain for OSS (e.g. oss.example.com) — a subdomain needs no separate filing. A domain registered abroad has to move to a registrar inside mainland China first.

One-shot ROS template (optional shortcut)

Let Resource Orchestration Service (ROS) build the private bucket, the RAM user limited to it and the AccessKey in one go.

  • Copy the whole template below first.
  • Paste it into Specify template → Enter template on the ROS create page.
  • Tick the safety confirmation, or creation is blocked.
  • When it fails, open the stack's Events: a taken bucket name is the most common cause.

ROS template

json
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": {
    "zh-cn": "为孤云创建:私有且阻止公共访问的 OSS Bucket、只授权该桶读写的 RAM 用户、以及该用户的 AccessKey。AccessKey ID 与 Secret 会出现在资源栈的「输出」里,复制回应用即可。",
    "en": "Creates, for Guyun: a private OSS bucket with public access blocked, a RAM user limited to that bucket, and an AccessKey for it. The AccessKey ID and secret appear in the stack outputs; copy them back into the app."
  },
  "Parameters": {
    "BucketName": {
      "Type": "String",
      "Label": {
        "zh-cn": "Bucket 名称",
        "en": "Bucket name"
      },
      "Description": {
        "zh-cn": "全局唯一。3–63 位,只能用小写字母、数字和短横线,首尾必须是字母或数字。例如 my-photos-2026。",
        "en": "Globally unique. 3–63 characters: lowercase letters, digits and hyphens, starting and ending with a letter or digit. For example my-photos-2026."
      },
      "AllowedPattern": "^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$",
      "MinLength": 3,
      "MaxLength": 63
    },
    "RamUserName": {
      "Type": "String",
      "Label": {
        "zh-cn": "RAM 用户名",
        "en": "RAM user name"
      },
      "Description": {
        "zh-cn": "给应用专用的子账号。如果账号下已经有同名用户,请改成别的名字再创建。",
        "en": "A dedicated sub-account for the app. If a user with this name already exists, pick another one."
      },
      "Default": "guyun-app",
      "AllowedPattern": "^[a-zA-Z0-9._-]{1,64}$",
      "MinLength": 1,
      "MaxLength": 64
    }
  },
  "Resources": {
    "Bucket": {
      "Type": "ALIYUN::OSS::Bucket",
      "Properties": {
        "BucketName": {
          "Ref": "BucketName"
        },
        "AccessControl": "private",
        "StorageClass": "Standard",
        "BlockPublicAccess": true
      }
    },
    "AppUser": {
      "Type": "ALIYUN::RAM::User",
      "Properties": {
        "UserName": {
          "Ref": "RamUserName"
        },
        "DisplayName": {
          "Fn::Sub": "孤云存储"
        },
        "Comments": {
          "Fn::Sub": "孤云专用存储用户;授权桶 ${BucketName} 的读写;随资源栈删除。"
        }
      }
    },
    "BucketPolicy": {
      "Type": "ALIYUN::RAM::ManagedPolicy",
      "DependsOn": "AppUser",
      "Properties": {
        "PolicyName": {
          "Fn::Sub": "guyun-${BucketName}-rw"
        },
        "Description": {
          "Fn::Sub": "Guyun: read and write ${BucketName} only. No bucket-level administration."
        },
        "PolicyDocument": {
          "Version": "1",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "oss:ListObjects",
                "oss:GetBucketLocation",
                "oss:ListMultipartUploads"
              ],
              "Resource": [
                {
                  "Fn::Sub": "acs:oss:*:*:${BucketName}"
                }
              ]
            },
            {
              "Effect": "Allow",
              "Action": [
                "oss:GetObject",
                "oss:PutObject",
                "oss:DeleteObject",
                "oss:AbortMultipartUpload",
                "oss:ListParts",
                "oss:RestoreObject"
              ],
              "Resource": [
                {
                  "Fn::Sub": "acs:oss:*:*:${BucketName}/*"
                }
              ]
            }
          ]
        },
        "Users": [
          {
            "Fn::GetAtt": [
              "AppUser",
              "UserName"
            ]
          }
        ]
      }
    },
    "AccessKey": {
      "Type": "ALIYUN::RAM::AccessKey",
      "DependsOn": "AppUser",
      "Properties": {
        "UserName": {
          "Fn::GetAtt": [
            "AppUser",
            "UserName"
          ]
        }
      }
    }
  },
  "Outputs": {
    "BucketName": {
      "Label": {
        "zh-cn": "Bucket 名称",
        "en": "Bucket name"
      },
      "Description": {
        "zh-cn": "填到应用的「Bucket 名称」里。",
        "en": "Paste into the app's bucket name field."
      },
      "Value": {
        "Ref": "BucketName"
      }
    },
    "RegionId": {
      "Label": {
        "zh-cn": "地域",
        "en": "Region"
      },
      "Description": {
        "zh-cn": "资源栈所在地域,也就是 Bucket 的地域。",
        "en": "The stack's region, which is the bucket's region."
      },
      "Value": {
        "Ref": "ALIYUN::Region"
      }
    },
    "Endpoint": {
      "Label": {
        "zh-cn": "HTTPS Endpoint",
        "en": "HTTPS endpoint"
      },
      "Description": {
        "zh-cn": "走默认域名时填到应用的「HTTPS Endpoint」里;如果之后绑了自定义域名,Endpoint 要改成那个域名。",
        "en": "With the default endpoint, paste this into the app's HTTPS endpoint field. If you bind a custom domain later, the endpoint becomes that domain instead."
      },
      "Value": {
        "Fn::Sub": "https://oss-${ALIYUN::Region}.aliyuncs.com"
      }
    },
    "AccessKeyId": {
      "Label": {
        "zh-cn": "AccessKey ID",
        "en": "AccessKey ID"
      },
      "Description": {
        "zh-cn": "复制后填到应用的「AccessKey ID」里。",
        "en": "Copy into the app's AccessKey ID field."
      },
      "Value": {
        "Fn::GetAtt": [
          "AccessKey",
          "AccessKeyId"
        ]
      }
    },
    "AccessKeySecret": {
      "Label": {
        "zh-cn": "AccessKey Secret",
        "en": "AccessKey secret"
      },
      "Description": {
        "zh-cn": "只在这里显示,复制后填进应用的 Keychain;不要粘贴到聊天、文档或代码里。",
        "en": "Shown here only. Copy it into the app's Keychain; never paste it into a chat, document or repository."
      },
      "Value": {
        "Fn::GetAtt": [
          "AccessKey",
          "AccessKeySecret"
        ]
      }
    }
  },
  "Metadata": {
    "ALIYUN::ROS::Interface": {
      "ParameterGroups": [
        {
          "Parameters": [
            "BucketName"
          ],
          "Label": {
            "default": "OSS"
          }
        },
        {
          "Parameters": [
            "RamUserName"
          ],
          "Label": {
            "default": "RAM"
          }
        }
      ],
      "Outputs": [
        "BucketName",
        "RegionId",
        "Endpoint",
        "AccessKeyId",
        "AccessKeySecret"
      ]
    }
  }
}

The template creates exactly the same resources and permissions as doing it by hand.

Console addresses

International site https://www.alibabacloud.com/; China site https://www.aliyun.com/.

Wording differs slightly between the two; use the equivalent button.

Copy these three values

They go into the matching fields on Guyun's Add storage screen: Place: pick the matching entry in the app (Beijing / Hong Kong / Guangzhou / us-west-004 …) — the region and the HTTPS endpoint are filled in for you.

This valueWhere it goes in Guyun
Bucket name
The bucket name from the console, globally unique, e.g. your-bucket-name.
Bucket name
Endpoint
Your domain, e.g. https://oss.example.com.
Endpoint
Key
The AccessKey ID and secret of the RAM user you just created.
AccessKey ID and secret

How to tell it worked

  • Guyun reports success and lists the bucket root; an empty bucket returning an empty list counts as success.
  • Then upload, download and delete one small file to confirm the domain can write as well as read.
  • If it fails, see common errors.

Go back to Guyun and choose Test connection & save.