You need to enable JavaScript to run this app.
Volcano Engine Function as a Service

Volcano Engine Function as a Service

Copy page
Download PDF
Call methods
Signature mechanism
Copy page
Download PDF
Signature mechanism
For each access request, the Volcano Engine verifies the identity of the access requestor through the access key (including Access Key ID and Secret Access Key) in the access signature information.​
Obtain access key​
Accounts and users with permission can create access keys in the following operation:​
  1. Use the root user or an IAM user with key management permissions to log in to the Identity and Access Management console.​
  1. In the left navigation bar select Resource Management > Key Management.​
  1. View the list of access keys for your account.​
  • Each account has a maximum of two access keys simultaneously.​
  • If the current account does not have the maximum number of access keys, click Create key to create a new access key. After creating, click View AccessKey details to view the information of the new access key.​
Create a normalization request​
tip​
  • Hash refers to the SHA256 algorithm.​
  • HexEncode refers to changing to hexadecimal encoding.​
​
CanonicalRequest = HTTPRequestMethod + '\n' + CanonicalURI + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + HexEncode(Hash(RequestPayload))​
​
Before signing, the request should be normalized so that the signature calculation process has no objections. The main process and pseudocode are as follows:​
​
Field​
Description​
HTTPRequestMethod​
HTTP request method, e.g. POST.​
CanonicalURI​
The normalized URI. If the URI is empty, then use/as an absolute path.​
CanonicalQueryString​
Normalized QueryString. The QueryString normalization process is as follows:​
  1. URL Encode the parameter name and parameter value of each QueryString.​
  1. Strict ordering of parameter names in ASCII byte order.​
  1. Connect the parameter names and parameter values in the right order using=Connect the parameter pairs according to sorted results using&Connect.​
​
CanonicalQueryString = "Action=ListUsers&Version=2018-01-01"​
​
CanonicalHeaders​
Header after normalization. The pseudocode is as follows:​
​
CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN​
​
​
CanonicalHeadersEntry = Lowercase(HeaderName) + ':' + Trimall(HeaderValue) + '\n'​
​
Among them, Lowercase means to convert all the names of the Header to lowercase, and Trimall means to remove the excess spaces before and after the value of the Header.​
warning​
  • You need to add line-changing characters: '\n' at the end.​
  • The order of the Header is ASCII sorted by the lowercase of the headerName.​
SignedHeaders​
The name of the Header participating in the signature. The signature Header should be included in the list of normalized Headers to indicate which Headers participate in the signature calculation, thus ignoring the additional Headers added by the proxy. If there are two Headers host and x-date, then they must be added to the list of normalized Header names. ​
The pseudocode is as follows:​
​
SignedHeaders = Lowercase(HeaderName0) + ';' + Lowercase(HeaderName1) + ";" + ... + Lowercase(HeaderNameN)​
​
RequestPayload​
Complete request body.​
  • The URL encodes the parameter name and parameter value of each QueryString (the same as the RFC3986 method).​
  • Here, the GET method needs to include all parameters of hash algorithm, trust certificate, signature date, and signature Header, etc.​
  • Strict ordering of parameter names in ASCII byte order.​
  • Connect the parameter names and parameter values in the right order using=Connect the parameter pairs according to sorted results using&Connect.​
​
Create signature string​
The signature string mainly contains the metadata information of the request and the normalization request. It consists of the signature algorithm, the request date, the trust certificate, and the normalization request hash value connection. The pseudocode is as follows:​
​
StringToSign = Algorithm + '\n' + RequestDate + '\n' + CredentialScope + '\n' + HexEncode(Hash(CanonicalRequest))​
​
The field description is as follows.​
​
Field​
Description​
Algorithm​
The algorithm for signature. The current Volcano Engine only supports the HMAC-SHA256 signature algorithm.​
RequestDate​
Request UTC time. Please use YYYYMMDD T'HHMMSS'Z'format, e.g.: 20201103T104027Z.​
CredentialScope​
Scope of credentials. The format is YYYYMMDD/region/service/request.​
CanonicalRequest​
The result of a preorder normalization request.​
​
Calculate signature key​
  1. Before calculating the signature, first derive the Signing Key from the Secret Access Key, rather than directly using the Secret Access Key. The specific calculation process is as follows:​
  • ​
    kSecret = *Your Secret Access Key*​
    kDate = HMAC(kSecret, Date)​
    kRegion = HMAC(kDate, Region)​
    kService = HMAC(kRegion, Service)​
    kSigning = HMAC(kService, "request")​
    ​
  1. Calculate the signature.​
  • ​
    Signature = HexEncode(HMAC(kSigning, StringToSign))​
    ​
  1. Build the Header.​
tip​
Use in the expression{}the content, representing the middle process calculated in the above.​
  • ​
    Authorization: HMAC-SHA256 Credential={AccessKeyId}/{CredentialScope}, SignedHeaders={SignedHeaders}, Signature={Signature}​
    ​
Sample code​
The following is the Golang implementation of the signature mechanism. After signing, the veFaaS OpenAPI ListFunctions interface is called. For signature algorithms and examples implemented in Python, Java, NodeJS, PHP, and more, please refer to volcengine/volc-openapi-demos.​
​
Packaging main​
​
Import (​
"Bytes"​
"Crypto/hmac"​
"Crypto/sha256"​
"Encoding/hex"​
"Fmt"​
"Log"​
"Net/http"​
"Net/http/htputil"​
"Net/url"​
"Strings"​
"Time"​
)​
​
Const (​
AccessKeyID = "AKxxx"​
SecretAccessKey = "yyyyy"​
​
Addr = "https://iam.volcengineapi.com"​
Path = "/" // path without Query​
​
Service = "vefaas"​
Region = "cn-Beijing"​
Action = "ListFunctions"​
Version = "2024-06-06"​
)​
​
Func hmacSHA256 (key [] bytes, content string) [] bytes {​
Mac: = hmac.New (sha256.New, key)​
Mac. Write ([] bytes (content))​
Returns mac. Sum (nil)​
}​
​
func getSignedKey (secretKey, date, region, service string) [] byte {​
kDate: = hmacSHA256 ([] bytes (secretKey), date)​
kRegion: = hmacSHA256 (kDate, region)​
kService: = hmacSHA256 (kRegion, service)​
kSigning: = hmacSHA256 (kService, "request")​
​
Return kSigning​
}​
​
Func hashSHA256 (data [] bytes) [] bytes {​
Hash: = sha256.New ()​
If _, err: = hash. Write (data); err! = nil {​
Log. Printf ("input hash err:% s", err. Error ())​
}​
​
Returns hash. Sum (nil)​
}​
​
func doRequest (method string, queries url. Values, body [] bytes) error {​
//1. Build request​
Queries. Set ("Action", Action)​
Queries. Set ("Version", Version)​
RequestAddr: = fmt. Sprintf ("% s% s?% s", Addr, Path, queries. Encode ())​
Log. Printf ("request addr:% s\ n", requestAddr)​
​
Request, err: = http. NewRequest (method, requestAddr, bytes. NewBuffer (body))​
If err! = nil {​
Returns fmt. Errorf ("bad request:% w", err)​
}​
​
//2. Build the signature material​
Now: = time.Now ()​
Date: = now. UTC (). Format ("20060102T150405Z")​
authDate: = date [: 8]​
Request. Header. Set ("X-Date", date)​
​
Payload: = hex. EncodeToString (hashSHA256 (body))​
Request. Header. Set ("X-Content-Sha256", payload)​
Request. Header. Set ("Content-Type", "application/x-www-form-urlencoded")​
​
queryString: = strings. Replace (queries. Encode (), "+", "% 20 ", -1)​
signedHeaders: = [] string {"host", "x-date", "x-content-sha256", "content-type"}​
Var headerList [] string​
For _, header: = range signedHeaders {​
If header == "host" {​
headerList = append (headerList, header + ":" + request.Host)​
} else {​
V: = request. Header. Get (header)​
headerList = append (headerList, header + ":" + strings. TrimSpace (v))​
}​
}​
headerString: = strings. Join (headerList, "\ n")​
​
canonicalString: = strings. Join ([] string {​
The method,​
Path,​
queryString,​
headerString + "\ n",​
Strings. Join (signedHeaders , ";"),​
Payload,​
}, "\ n")​
Log. Printf ("canonical string:\ n% s\ n", canonicalString)​
​
hashedCanonicalString: = hex. EncodeToString (hashSHA256 ([] byte (canonicalString)))​
Log. Printf ("hashed canonical string:% s\ n", hashedCanonicalString)​
​
credentialScope: = auth Date + "/" + Region + "/" + Service + "/request"​
signString: = strings. Join ([] string {​
"HMAC-SHA256",​
The date,​
CredentialScope,​
hashedCanonicalString,​
}, "\ n")​
Log. Printf ("sign string:\ n% s\ n", signString)​
​
//3. Build the authentication request header​
signedKey: = getSignedKey (SecretAccessKey, authDate, Region, Service)​
Signature: = hex. EncodeToString (hmacSHA256 (signedKey, signString))​
Log. Printf ("signature:% s\ n", signature)​
​
Authorization: = "HMAC-SHA256" +​
"Credential =" + AccessKey ID + "/" + credential Scope +​
", SignedHeaders =" + strings. Join (signedHeaders , ";") +​
", Signature =" + signature​
Request. Header. Set ("Authorization", authorization)​
Log. Printf ("authorization:% s\ n", authorization)​
​
//4. Print the request and initiate the request​
requestRaw, err: = htputil. DumpRequest (request, true)​
If err! = nil {​
Returns fmt. Errorf ("dump request err:% w", err)​
}​
​
Log. Printf ("request:\ n% s\ n", string (requestRaw))​
​
Response, err: = http.DefaultClient.Do (request)​
If err! = nil {​
Returns fmt. Errorf ("do request err:% w", err)​
}​
​
//5. Print response​
responseRaw, err: = htputil. DumpResponse (response, true)​
If err! = nil {​
Returns fmt. Errorf ("dump response err:% w", err)​
}​
​
Log. Printf ("response:\ n% s\ n", string (responseRaw))​
​
If response. StatusCode == 200 {​
Log. Printf ("Request successful")​
} else {​
Log. Printf ("Request failed")​
}​
​
Return nil​
}​
​
Func main () {​
//GET request example​
Query1: = make (url. Values)​
doRequest (http. MethodGet, query1, nil)​
​
}​
​
​
Last updated: 2025.06.30 11:48:53