NAS API Protocol

The protocol

Apps that require access to the NAS OS backend can use the NAS backend API. You can communicate with the backend API with HTTP POST requests. The methods inputs are set into a JSON structure. The result is also a JSON structure.

We can use the curl command line to issue some test requests. For this purpose, you will first need to set the $NAS_IP environment variable to the hostname or IP of you NAS:

export NAS_IP=<your_nas_ip>

Here is a first example with a public method which don’t take parameters:

curl -s -d'{}' http://$NAS_IP/api/external/5.0/system.System.get_infos | python -m json.tool

Note that the HTTP request returns the JSON structure on a single line. This is why we pipe the output into the python json.tool module, to present a properly indented output. Here is a partial view of the result:

{
    "infos": {
        "__sub_version__": 0,
        "__version__": 5,
        "__type__": "GeneralInfo",
        "__properties__": {
            "product": "6-Bay NAS Pro",
            "product_id": "superbee6",
            "vendor_name": "Seagate"
            ...
        }
    }
}

A second example where we call the list_volumes method of the volumes.VolumeAdministration service. This requires a list_info object in which we can control the returned result, by specifying an offset and a limit:

curl -s -d'{
    "list_info": {
        "__type__": "ListInfo",
        "__properties__": {
            "offset": 0,
            "limit": -1
        }
    }
}' http://$NAS_IP/api/external/5.0/volumes.VolumeAdministration.list_volumes \
| python -m json.tool

The partial result properly indented:

{
    "volumes": {
        "__total_items__": 2,
        "__sub_type__": "Volume",
        "__elements__": [
            {
                "__sub_version__": 0,
                "__version__": 5,
                "__type__": "Volume",
                "__properties__": {
                    "friendly_name": "Volume 1",
                    "id": 1,
                    ...
                }
            },
            ...
        ],
        "__type__": "ResultSet"
    }
}

Note

Refer to the NAS API Reference for a comprehensive documentation on the available APIs.


App Authentication

If an application requires some higher accesses, it should register with the NAS backend.

The first step is to register itself to explicitly define the APIs it will be using. For this, the URL is :

http://$NAS_IP/api/external/authenticate/application

Use the following input with the ID of the app and the list of needed services.

{
    "app_id": "com.seagate.my_app",
    "mandatory_perms":[
        ...
    ],
    "optional_perms":[
        ...
    ]
}

For example:

curl -d '{
    "app_id": "com.seagate.my_app",
    "mandatory_perms":["v5.0.sharing.shares.Administration"],
    "optional_perms":[]
}' http://$NAS_IP/api/external/authenticate/application

This should return a request id (req_id), which looks like:

{"req_id": "b2fb46d6c05e42c69721c7120b8a9a24"}

Now we have to poll until the access is granted or denied. Local applications are automatically granted. But others could have to wait a user authorization:

curl -s http://$NAS_IP/api/external/authenticate/application/<req_id> \
| python -m json.tool

Which should return something like:

{
    "status": "granted",
    "token": "467e2fe04bb935ca14c9f515c9fecf8d4af03013"
}

If you want to unregister this application, use the following url with the app’s token:

curl -d '{"token": <token>}' \
http://$NAS_IP/api/external/authenticate/application/unregister/com.seagate.my_app

App Session

The second step is to open a session. An application doesn’t use directly the previous app’s token (token) to authenticate with the NAS. It uses a session’s token (session_token). To do so, the application requests a challenge to the NAS:

curl -s http://$NAS_IP/api/external/authenticate/app_login \
| python -m json.tool

Which should return something like:

{
    "challenge_id": 0,
    "challenge": "40668617129812"
}

We then use the challenge and the token to generate a secret, as follows:

echo -n "<challenge><token>" | sha1sum | awk '{print $1}'
4ee0523b60ab58d3994c3383ff5571aba89466ed

We can now send this ticket to the NAS:

curl -d -s '{
    "app_id": "com.seagate.my_app",
    "challenge_id": <challenge_id>,
    "secret": <secret>
}' http://$NAS_IP/api/external/authenticate/app_login | python -m json.tool

Which should return something like:

{
    "expiration_date": 1425396107,
    "session_token": "f561c391438692c5100de9cf66ef326f659424b4"
}

If the secret matches the expected result, the NAS returns the session_token that can be used in each requests:

curl -H"Authentication: APP_AUTH <session_token>" -d "{...}" \
http://$NAS_IP/api/external/...

User Authentication

If the app wants to use the privileges of a user, we need to log with the webboard, using the following URL:

/?app_session_token=<session_token>&app_path=/path_to_the_application

Once logged in the NAS will call the redirect to app with the parameter user_token into the URL. It can be kept and used in each request with the session_token.

curl -H"Authentication: APP_AUTH <session_token>" \
-H"APP_USER: <user_token>" -d "{...}" > http://$NAS_IP/api/external/...