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 upload or select an HTTPS certificate.
    • Add a CNAME record at your current DNS provider, pointing at the public endpoint OSS gives you (follow whatever the console currently shows).
  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 and enter the bucket name, region and key — the endpoint is your domain, e.g. https://oss.example.com.
    • Choose the custom domain (CNAME) addressing mode, then 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"],
      "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.

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.

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"
              ],
              "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」里(地址方式选「Bucket 子域名」);如果之后绑了自定义域名,Endpoint 要改成那个域名。",
        "en": "With the default endpoint, paste this into the app's HTTPS endpoint field (addressing: virtual host). 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 four values

They go into the matching fields on Guyun's Add storage screen:

This valueWhere it goes in Guyun
Bucket name
The bucket name from the console, globally unique, e.g. your-bucket-name.
Bucket name
Region
The mainland region code the bucket lives in, e.g. cn-beijing.
Region
Endpoint
Your domain, e.g. https://oss.example.com; choose the custom domain (CNAME) addressing mode.
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.