Graceful Shutdown

0
Hello everyone,   Does anybode now the correct flow go execute a graceful shutdown of an IED? I'm stuck on the step 3: Generate authtoken for accessing the API via auth-api-path + /token/permit with the apptoken as part of the body   I'm using a http request POST url: "https://edge-iot-core.proxy-redirect:8443/a.service/api/v3/token/permit" and I only get 503 Service Unavailable.   Thanks.
asked
3 answers
0

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"}

answered
0

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. Get auth token from device API
  2. Call shutdown endpoint with your parameters
  3. Handle response (or timeout for instant shutdown)

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:

  • auth-api-path - Path to auth API (e.g., "a.service/api/v3")
  • edge-certificates.certificate-chain - Internal proxy-redirect certificate as a single base64-encoded string

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:

  • maxAckTimeForApps - Seconds to wait for apps to acknowledge (1-30)
  • executeNow - true = immediate shutdown, false = create shutdown job

Expected Responses:

Scenario 1: Job created (executeNow: false)

  • Status: 200
  • Body: Empty
  • Behavior: Device responds, then shuts down after delay

Scenario 2: Instant shutdown (executeNow: true)

  • Status: No response
  • Body: -
  • Behavior: Network dies immediately, request times out

Hope this helps! Let me know if you have any questions.

answered
-1

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:

  1. Auth API service must be running in the Edge environment.
  2. If the authentication service is not deployed or not healthy, the proxy will return 503.
  3. Correct network route
  4. The call must be reachable from your client/container to the Auth API service, not the device service proxy.
  5. Correct request body format
  6. The request body must contain the apptoken exactly as expected by the API (usually JSON).

Example:


{
  "apptoken": "your_app_token_here"
}

  1. Content-Type header
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.


answered