Hi Henrique,
Try doing this way:
First make sure this is the correct path: "/a.service/api/v3/token/permit"
Then try doing this way:
curl -k -X POST \
https://edge-iot-core.proxy-redirect:8443/a.service/api/v3/token/permit \
-H "Content-Type: application/json" \
-d '{ "appToken": "<PASTE_REAL_APP_TOKEN_HERE>" }'
This should have the following expected response:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
Save the token for example as:
AUTH_TOKEN
Finally try this:
curl -k -X POST \
https://edge-iot-core.proxy-redirect:8443/a.service/api/v3/device/shutdown \
-H "Authorization: Bearer <AUTH_TOKEN>"
This should have the following expected response:
{ "status": "accepted"}
Hey Henrique,
As the current documentation of this feature is a bit sparse, here's a more extensive explanation with implementation examples:
Quick Start: Implementing the Device Shutdown API
Prerequisites
⚠️ Required: Your application must declare the API.Shutdown device feature during version creation:
iectl publisher sa version create \
-a "myapp" \
-v "1.0.0" \
-d "API.Shutdown" \
...
Without this flag, the shutdown API will reject your requests with 403 Forbidden.
Overview
The Device Shutdown API allows your app to gracefully shut down an Industrial Edge Device. The process:
1. Read Configuration Files
Your app needs access to two mounted files:
// Certificate and IP information
certsips := readFile("/var/run/edgedevice/certsips.json")
// Your app's authentication token
appToken := readFile("/etc/edgeconfig/.apptoken")
Certificate structure in certsips.json:
{
"auth-api-path": "a.service/api/v3",
"edge-certificates": {
"certificate-chain": "LS0tLS1CRUdJTi...",
"service-name": "edge-iot-core.proxy-redirect"
}
}
Key fields:
Note: For on-device apps making internal API calls, only load edge-certificates.certificate-chain. The cert-chain field exists in certsips.json but is only for external clients.
2. Get Authentication Token
Exchange your app token for an access token:
POST https://edge-iot-core.proxy-redirect:443/device/edge/{auth-api-path}/token/permit
Content-Type: application/json
{
"appPrimaryToken": "your-app-token"
}
Response:
{
"access_token": "eyJhbGc...",
"expires_in": 3600,
"token_type": "Bearer"
}
3. Create TLS Configuration
Extract and decode certificate from certsips.json for secure communication:
import (
"crypto/tls"
"crypto/x509"
"encoding/base64"
)
func createTLSConfig(certsips CertsIPs) (*tls.Config, error) {
certPool := x509.NewCertPool()
// Load only internal edge-certificates.certificate-chain
// We don't need cert-chain (external nginx cert) for internal API calls
if certsips.EdgeCertificates == nil || certsips.EdgeCertificates.CertificateChain == "" {
return nil, fmt.Errorf("edge-certificates.certificate-chain not found")
}
certPEM, err := base64.StdEncoding.DecodeString(certsips.EdgeCertificates.CertificateChain)
if err != nil {
return nil, fmt.Errorf("decoding edge-certificates: %w", err)
}
if ok := certPool.AppendCertsFromPEM(certPEM); !ok {
return nil, fmt.Errorf("failed to parse edge certificate")
}
return &tls.Config{
RootCAs: certPool,
}, nil
}
4. Call Shutdown API
POST https://edge-iot-core.proxy-redirect:443/device/edge/api/v2/shutdown
Content-Type: application/json
Authorization: Bearer {access_token}
{
"maxAckTimeForApps": 30,
"executeNow": true
}
Parameters:
Expected Responses:
Scenario 1: Job created (executeNow: false)
Scenario 2: Instant shutdown (executeNow: true)
Hope this helps! Let me know if you have any questions.
Hi,
A 503 from /api/v3/token/permit usually means the request never reaches the auth service. In most cases the issue is the endpoint you are calling.
For the Edge API, /token/permit must be called on the Auth API endpoint, not through the edge-iot-core.proxy-redirect path. That proxy endpoint is typically used for device services and will return 503 if the auth service is not exposed through it.
So instead of calling:
https://edge-iot-core.proxy-redirect:8443/a.service/api/v3/token/permit
you should call the Auth API base URL directly, something like:
https://<auth-api-host>/api/v3/token/permit
and send the apptoken in the request body as required by the auth API.
Also check these points:
apptoken exactly as expected by the API (usually JSON).Example:
{
"apptoken": "your_app_token_here"
}
Content-Type: application/json
Once the token is successfully generated, you can use that token in the next step of the graceful shutdown flow.
So in short, the 503 is typically caused by calling the proxy endpoint instead of the authentication API endpoint, or the auth service not being available behind that proxy. Adjusting the endpoint usually resolves the issue.