アプリケーション - Actcast エージェント間通信について

アプリケーション - Actcast エージェント間の通信 #

アプリケーションと Actcast エージェントは UNIX ドメインソケットで通信します。通信には大別してコマンドとサービスの 2 種類があります。

コマンドは Actcast エージェントがリクエストし、アプリケーションがレスポンスを返します。 用いるソケットのパスはアプリ起動時に環境変数 ACTCAST_COMMAND_SOCK で指定されます。

サービスはアプリケーションがリクエストし、Actcast エージェントがレスポンスを返します。 用いるソケットのパスはアプリ起動時に環境変数 ACTCAST_SERVICE_SOCK で指定されます。

プロトコル #

コマンドおよびサービスのどちらも、同じプロトコルを用います。

接続はリクエストのたびに行います。接続した側はレスポンスを受信したらコネクションを終了します。

リクエストレスポンス形式のプロトコルを用います。このプロトコルはシンプルな独自テキストプロトコルを用います。

  • リクエスト - <Request ID> <コマンド数値またはサービス数値> <len> <データ>
  • レスポンス - <Request ID> <ステータス> <len> <データ>

ここで <len><データ> のバイト数を表わします。

ステータス #

OK が正常、それ以外は異常ステータスです。

ステータス数値意味
OK0正常に返り値を返す
Busy1リソースが busy 状態ですぐに応答できない
Unimplemented2アプリケーションが実装していないコマンドがきた
DeviceError3デバイスが異常ステータスを返した/デバイスが存在しない
AppError4アプリケーション固有エラー
GeneralError5上記に当てはまらないエラー

コマンド #

コマンド数値 #

コマンドの各種コマンド数値は以下の通りです。

コマンド数値ペイロードレスポンス
Take Photo0-image データ

Take Photo #

Take Photo コマンドはユーザが Web UI で [撮影] を押したときに送られます。 アプリケーションはこのコマンドを受け取ったら現在の設定で撮影をし、そのデータを返します。レスポンスのデータはdata URL形式です。

#
<- 1 0 0
-> 1 0 386 data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7

サービス #

サービス数値 #

サービスの各種サービス数値は以下の通りです。

サービス数値ペイロードレスポンス
RS2560メッセージ署名

RS256 #

リクエストメッセージにデバイス秘密鍵を用いて RSA-SHA256 による署名を行い、生成した署名をレスポンスとして返します。 ペイロードとレスポンスはどちらも base64url エンコードされたバイト列です。 署名を検証するには別途 Actcast API からデバイス固有の証明書を取得する必要があります。

actsim では、デバイス秘密鍵の代わりに Act 起動毎にランダムに生成された秘密鍵を用いて署名します。

RS256 および検証の例 #

Hello, Actcast! というバイト列の署名を作成する場合。

<- 1 0 20 SGVsbG8sIEFjdGNhc3Qh
-> 1 0 342 F9UfGKDAk0Xp7vPX029hJ4TGyXSkPX4LGFT4cKETUPH_nHrHWIzPvUtNDpgm52X_Ya9wb4mAa0eLV5QpjFq4wS0gIyToSJ6Ov-H8-CcxJHr_-caRLGj8ooRRBF6EbSiCCXj-rCyUme8uBybM5UAo235DUL2bvwf3U1LagLtGounK4chv1aEAFnjSfuhevyBCLegavSAKOMsL_7MCqVvI7XgB2vYJF-c5o2bP9Nt530AoYUAmIvdOxkiMzjaDlat0SNpE59gyu03JX7QQxQphs1TW0qMB42Rvm9Cia5wDsllLt3glwHiJI6xNsJQR_3lxyXzicl1CAl3EyGg51Gz1Hg

ただしデバイス秘密鍵は以下のような想定。

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAyOhtBJ2x7PJw59W1eY63i4jab1N+tBO9q7Wmoq0AB0+914I9
jJ/MNEpFpieOQGy+wi5OjNFzj5RZIHICWDkRBhsc0l18i+z3jcCoQq8JfFiy7EJV
N/iNttE4Y1aRoARJlPM7DKNOydhphd5nU2RCEFKcnPNFyjkB4S7a7QtVlqQuIQij
SUG00HatGfSD3DKW7mgWrRqQY9mNUjqs2HaDG9muoHJ8hpHN34QKfISusAmRuun9
2XGybus+mG1Tcj9vKVvpb8a381wxcCDTZOiAHlCmNwnX/5sbLm8HNFmaBSZ3K0ud
AQTHXxnYBH5m6ksGuNiicxg0RzikHRBN0IYNIQIDAQABAoIBAHhekNqAJJbjFnRA
HS9MK3nFL6Idcz8uyKe0+LZkUi0PQJ164ad8Iht+GEaZUmgU/yFWHyfNYaA3cEK5
K+BxqFpxKg57hmBLRHJAaE8zkcpXVjOo9mfHWhibN16FAlDN4MwGAm3q9gyGxYo4
Gs3itpYS+NQsCLdE+nRQ30fAT7IlcTsNe3RO40cC8Am3MhBRu1fIw4wY4IwUnqNz
o+FniygOUjTpYE2hj5MevQQT+6yVwjra7BDRcCdxdJIBpO5mURp36gxJC8CzxW0y
A8PI1uubuINoxbMBm+p3tWuPoZz3ezgzvtPN15+gJwYhCltpT7KLIT/fsQRLHZB0
Hx/JBsUCgYEA8wD49Pu1WOhLUseQNfq+9mA/WmCIgILd1eltR2WK9CcpZEfKz6ju
jyYmUnkX51YEtWC1xpo5w/PqGuELXp7WghnxvDplQyuIajnV8gF4zlKOd793wxt+
/+iBWvFelxGb2dZnUg/6mdzGHFrevwtu4qKmKs4PaZx9WnhqlA0Bfq8CgYEA06cb
ltiWW0gbWKyyMPLuvibfKfg27+SZxXPbrCfmioFiAWUNRZyT1LN/CLrOsC0y9Prs
L4DMQdmW+j2pvwzariOWP0EH7Q88N9DXbZQYnjN1U0brAtAmkkJP91XcjMT++OXT
wiILc+7UwXT0zsVw/mw6H3o0xmPY8nnpgHE3pS8CgYB2JerlcdxiNc8pmE3NcPSX
5YPn9TdpBDfHYY74P66ntsKxNxaskH4sq2fGgYnVuEThyvuWbDXZyCXym6hjgOba
qrKVye6iEfBpdWVIHN8XsZwDLNyVyDCfS/RYuzI6UR1tdIkXpR064dSQxL24NV7c
YihYd4eW2bc43YM0KH6pkQKBgEMQaj+L9WiLGo8oeXXlJB0AeCn2SoIM72SPZ4XP
Rs+QW5uRh3kNOhJlpdUATEmqqMDTWU9cAlzDM4GrVEQDMK+I+yyj0H0fHLea5wgD
qyFFsOFoUUMc7XveozP98tpv+VKokEatPu/HN4btJjz2du1HIcujj2FldfKvCnv2
Y+llAoGBAMjFdKDiXHumLmDXlYBhzsz92hXr1WyYS8GkfyIR0qedHTRmpIDjNz7w
kWMMhCuPJtA+NY8JZi7iDRgo7uOYpq+T2pRMY1Bz/VoiAZpkECk931Eh7ebL/1X6
JbV3NIuWiFqLi2r5zqoRZS1k7zgpGPrfxtJ2PcIt/1HpYN9zCP6T
-----END RSA PRIVATE KEY-----

このとき、Actcast API で以下の公開鍵を取得できる。

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyOhtBJ2x7PJw59W1eY63
i4jab1N+tBO9q7Wmoq0AB0+914I9jJ/MNEpFpieOQGy+wi5OjNFzj5RZIHICWDkR
Bhsc0l18i+z3jcCoQq8JfFiy7EJVN/iNttE4Y1aRoARJlPM7DKNOydhphd5nU2RC
EFKcnPNFyjkB4S7a7QtVlqQuIQijSUG00HatGfSD3DKW7mgWrRqQY9mNUjqs2HaD
G9muoHJ8hpHN34QKfISusAmRuun92XGybus+mG1Tcj9vKVvpb8a381wxcCDTZOiA
HlCmNwnX/5sbLm8HNFmaBSZ3K0udAQTHXxnYBH5m6ksGuNiicxg0RzikHRBN0IYN
IQIDAQAB
-----END PUBLIC KEY-----

上記の RS256 コマンドの結果を検証するには例えばコマンドで以下のように行う。

元データを用意。

$ printf 'Hello, Actcast!' > test.txt

公開鍵を取得。

$ cat <<EOF > public-key.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyOhtBJ2x7PJw59W1eY63
i4jab1N+tBO9q7Wmoq0AB0+914I9jJ/MNEpFpieOQGy+wi5OjNFzj5RZIHICWDkR
Bhsc0l18i+z3jcCoQq8JfFiy7EJVN/iNttE4Y1aRoARJlPM7DKNOydhphd5nU2RC
EFKcnPNFyjkB4S7a7QtVlqQuIQijSUG00HatGfSD3DKW7mgWrRqQY9mNUjqs2HaD
G9muoHJ8hpHN34QKfISusAmRuun92XGybus+mG1Tcj9vKVvpb8a381wxcCDTZOiA
HlCmNwnX/5sbLm8HNFmaBSZ3K0udAQTHXxnYBH5m6ksGuNiicxg0RzikHRBN0IYN
IQIDAQAB
-----END PUBLIC KEY-----
EOF

RS256 で署名を得る。 エンコードされたデータをワンライナーで処理する。パディングはデータに依存することに注意。

$ echo F9UfGKDAk0Xp7vPX029hJ4TGyXSkPX4LGFT4cKETUPH_nHrHWIzPvUtNDpgm52X_Ya9wb4mAa0eLV5QpjFq4wS0gIyToSJ6Ov-H8-CcxJHr_-caRLGj8ooRRBF6EbSiCCXj-rCyUme8uBybM5UAo235DUL2bvwf3U1LagLtGounK4chv1aEAFnjSfuhevyBCLegavSAKOMsL_7MCqVvI7XgB2vYJF-c5o2bP9Nt530AoYUAmIvdOxkiMzjaDlat0SNpE59gyu03JX7QQxQphs1TW0qMB42Rvm9Cia5wDsllLt3glwHiJI6xNsJQR_3lxyXzicl1CAl3EyGg51Gz1Hg | tr -- -_ +/ | sed 's/$/==/' | base64 -d > signature.dat

OpenSSL で検証する。

$ openssl dgst -sha256 -verify public-key.pem -signature signature.dat test.txt
Verified OK

Python による RS256 サービスの実装 も参照してください。

想定される使い方 #

Actcast アプリとそのアプリが依存する API (以後 Web API)があるとします。 今、 Act が Web API との間でデータを送受信したいとします。 この通信の際に正しいデバイスからのものだけを受け付けたいです。 例えば、 AWS のセッショントークンなどの秘匿情報を取得したり、モデルが生成したデータ(Act Log 相当)を送信する、等が上げられます。

このような状況では、 Act は RS256 コマンドを使用して Web API から(Act と Web API 独自の)アクセストークンを取得し、それを以降のリクエストに用いるべきです。 Web API はアクセストークンをなんらかのデータベースを用いて適切に管理する必要があります。 アクセストークンには短い有効期間が設定されるべきです。 Act はアクセストークンを再発行する時、以前の RS256 コマンドの結果を使いまわしてはいけません。(必ず RS256 コマンドを再度発行する) これはデバイス証明書が予告なく更新される可能性があるためです。

agent
 |   act
 |    | web-api
 |    |    | actcast-api
 |    |    |    |
 |<---x    |    | request an signature
 x--->|    |    | return an signature
 |    x--->|    | request access token using the signature
 |    |    x--->| request the public key of the device
 |    |    |<---x return the public key of the device
 |    |    x    | verify the signature
 |    |<---x    | issue an access token (with expire date, e.g. 4 hours)
 |    |    |    |
 |    x--->|    | send something using access token (use lightweight signature, e.g. hs256)
 |    |    |    |

Actcast SDKリファレンスマニュアル に戻る