Controlling access to Kinesis Video Streams resources using Amazon IoT - Amazon Kinesis Video Streams
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Controlling access to Kinesis Video Streams resources using Amazon IoT

This section describes how to enable a device (for example, a camera) to send audio and video data to one particular Kinesis video stream only. You can do this by using the Amazon IoT credentials provider and an Amazon Identity and Access Management (IAM) role.

Devices can use X.509 certificates to connect to Amazon IoT using TLS mutual authentication protocols. Other Amazon Web Services (for example, Kinesis Video Streams) don't support certificate-based authentication, but can be called using Amazon credentials in Amazon Signature Version 4 format. The Signature Version 4 algorithm typically requires the caller to have an access key ID and a secret access key. Amazon IoT has a credentials provider that allows you to use the built-in X.509 certificate as the unique device identity to authenticate Amazon requests (for example, requests to Kinesis Video Streams). This removes the need to store an access key ID and a secret access key on your device.

The credentials provider authenticates a client (in this case, a Kinesis Video Streams SDK that's running on the camera that you want to send data to a video stream) using an X.509 certificate and issues a temporary, limited-privilege security token. You can use the token to sign and authenticate any Amazon request (in this case, a call to the Kinesis Video Streams). For more information, see Authorizing Direct Calls to Amazon Services.

This way of authenticating your camera's requests to Kinesis Video Streams requires you to create and configure an IAM role and attach appropriate IAM policies to the role so that the Amazon IoT credentials provider can assume the role on your behalf.

For more information about Amazon IoT, see Amazon IoT Core Documentation. For more information about IAM, see Amazon Identity and Access Management (IAM).

Amazon IoT ThingName as stream name

Step 1: Create an Amazon IoT thing type and an Amazon IoT thing

In Amazon IoT, a thing is a representation of a specific device or logical entity. In this case, an Amazon IoT thing represents your Kinesis video stream that you want to configure resource-level access control. In order to create a thing, first, you must create an Amazon IoT thing type. You can use Amazon IoT thing types to store description and configuration information that's common to all things associated with the same thing type.

  1. The following example command creates a thing type kvs_example_camera:

    aws --profile default iot create-thing-type --thing-type-name kvs_example_camera > iot-thing-type.json
  2. This example command creates the kvs_example_camera_stream thing of the kvs_example_camera thing type:

    aws --profile default iot create-thing --thing-name kvs_example_camera_stream --thing-type-name kvs_example_camera > iot-thing.json

Step 2: Create an IAM role to be assumed by Amazon IoT

IAM roles are similar to users, in that a role is an Amazon identity with permissions policies that determine what the identity can and can't do in Amazon. A role can be assumed by anyone who needs it. When you assume a role, it provides you with temporary security credentials for your role session.

The role that you create in this step can be assumed by Amazon IoT to obtain temporary credentials from the security token service (STS) when performing credential authorization requests from the client. In this case, the client is the Kinesis Video Streams SDK that's running on your camera.

Perform the following steps to create and configure this IAM role:

  1. Create an IAM role.

    The following example command creates an IAM role called KVSCameraCertificateBasedIAMRole:

    aws --profile default iam create-role --role-name KVSCameraCertificateBasedIAMRole --assume-role-policy-document 'file://iam-policy-document.json' > iam-role.json

    You can use the following trust policy JSON for the iam-policy-document.json:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "credentials.iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. Next, attach a permissions policy to the IAM role that you previously created. This permissions policy allows selective access control (a subset of supported operations) for an Amazon resource. In this case, the Amazon resource is the video stream that you want your camera to send data. In other words, once all the configuration steps are complete, this camera will be able to send data only to this video stream.

    aws --profile default iam put-role-policy --role-name KVSCameraCertificateBasedIAMRole --policy-name KVSCameraIAMPolicy --policy-document 'file://iam-permission-document.json'

    You can use the following IAM policy JSON for the iam-permission-document.json:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kinesisvideo:DescribeStream", "kinesisvideo:PutMedia", "kinesisvideo:TagStream", "kinesisvideo:GetDataEndpoint" ], "Resource": "arn:aws:kinesisvideo:*:*:stream/${credentials-iot:ThingName}/*" } ] }

    Note that this policy authorizes the specified actions only on a video stream (Amazon resource) that is specified by the placeholder (${credentials-iot:ThingName}). This placeholder takes on the value of the Amazon IoT thing attribute ThingName when the Amazon IoT credentials provider sends the video stream name in the request.

  3. Next, create a Role Alias for your IAM role. Role alias is an alternate data model that points to the IAM role. An Amazon IoT credentials provider request must include a role-alias to indicate which IAM role to assume to obtain the temporary credentials from the STS.

    The following sample command creates a role alias called KvsCameraIoTRoleAlias,

    aws --profile default iot create-role-alias --role-alias KvsCameraIoTRoleAlias --role-arn $(jq --raw-output '.Role.Arn' iam-role.json) --credential-duration-seconds 3600 > iot-role-alias.json
  4. Now you can create the policy that will enable Amazon IoT to assume role with the certificate (once it is attached) using the role alias.

    The following sample command creates a policy for Amazon IoT called KvsCameraIoTPolicy.

    aws --profile default iot create-policy --policy-name KvsCameraIoTPolicy --policy-document 'file://iot-policy-document.json'

    You can use the following command to create the iot-policy-document.json document JSON:

    cat > iot-policy-document.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:AssumeRoleWithCertificate" ], "Resource": "$(jq --raw-output '.roleAliasArn' iot-role-alias.json)" } ] } EOF

Step 3: Create and configure the X.509 certificate

Communication between a device (your video stream) and Amazon IoT is protected through the use of X.509 certificates.

  1. Create the certificate to which you must attach the policy for Amazon IoT that you previously created.

    aws --profile default iot create-keys-and-certificate --set-as-active --certificate-pem-outfile certificate.pem --public-key-outfile public.pem.key --private-key-outfile private.pem.key > certificate
  2. Attach the policy for Amazon IoT (KvsCameraIoTPolicy created previously) to this certificate.

    aws --profile default iot attach-policy --policy-name KvsCameraIoTPolicy --target $(jq --raw-output '.certificateArn' certificate)
  3. Attach your Amazon IoT thing (kvs_example_camera_stream) to the certificate you just created:

    aws --profile default iot attach-thing-principal --thing-name kvs_example_camera_stream --principal $(jq --raw-output '.certificateArn' certificate)
  4. To authorize requests through the Amazon IoT credentials provider, you need the Amazon IoT credentials endpoint, which is unique to your Amazon Web Services account ID. You can use the following command to get the Amazon IoT credentials endpoint.

    aws --profile default iot describe-endpoint --endpoint-type iot:CredentialProvider --output text > iot-credential-provider.txt
  5. In addition to the X.509 certificate created previously, you must also have a CA certificate to establish trust with the backend service through TLS. You can get the CA certificate using the following command:

    curl --silent 'https://www.amazontrust.com/repository/SFSRootCAG2.pem' --output cacert.pem

Step 4: Test the Amazon IoT credentials with your Kinesis video stream

Now you can test the Amazon IoT credentials that you've set up so far.

  1. First, create a Kinesis video stream that you want to test this configuration with.

    Important

    Create a video stream with a name that is identical to the Amazon IoT thing name that you created in the previous step (kvs_example_camera_stream).

    aws kinesisvideo create-stream --data-retention-in-hours 24 --stream-name kvs_example_camera_stream
  2. Next, call the Amazon IoT credentials provider to get the temporary credentials:

    curl --silent -H "x-amzn-iot-thingname:kvs_example_camera_stream" --cert certificate.pem --key private.pem.key https://IOT_GET_CREDENTIAL_ENDPOINT/role-aliases/KvsCameraIoTRoleAlias/credentials --cacert ./cacert.pem > token.json
    Note

    You can use the following command to get the IOT_GET_CREDENTIAL_ENDPOINT:

    IOT_GET_CREDENTIAL_ENDPOINT=`cat iot-credential-provider.txt`

    The output JSON contains the accessKey, secretKey, and the sessionToken, which you can use to access the Kinesis Video Streams.

  3. For your test, you can use these credentials to invoke the Kinesis Video Streams DescribeStream API for the sample kvs_example_camera_stream video stream.

    AWS_ACCESS_KEY_ID=$(jq --raw-output '.credentials.accessKeyId' token.json) AWS_SECRET_ACCESS_KEY=$(jq --raw-output '.credentials.secretAccessKey' token.json) AWS_SESSION_TOKEN=$(jq --raw-output '.credentials.sessionToken' token.json) aws kinesisvideo describe-stream --stream-name kvs_example_camera_stream

Step 5: Deploying Amazon IoT certificates and credentials on your camera's file system and streaming data to your video stream

Note

The steps in this section describe sending media to a Kinesis video stream from a camera that's using the Using the C++ Producer Library.

  1. Copy the X.509 certificate, the private key, and the CA certificate generated in the previous steps to your camera's file system. Specify the paths for where these files are stored, the role alias name, and the Amazon IoT credentials endpoint for running the gst-launch-1.0 command or your sample application.

  2. The following sample command uses Amazon IoT certificate authorization to send video to Kinesis Video Streams:

    gst-launch-1.0 rtspsrc location=rtsp://YourCameraRtspUrl short-header=TRUE ! rtph264depay ! video/x-h264,format=avc,alignment=au ! h264parse ! kvssink stream-name="kvs_example_camera_stream" aws-region="YourAWSRegion" iot-certificate="iot-certificate,endpoint=credential-account-specific-prefix.credentials.iot.aws-region.amazonaws.com,cert-path=/path/to/certificate.pem,key-path=/path/to/private.pem.key,ca-path=/path/to/cacert.pem,role-aliases=KvsCameraIoTRoleAlias"

Amazon IoT CertificateId as stream name

To represent your device (for example, your camera) through an Amazon IoT thing, but authorize a different stream name, then you can use the Amazon IoT certificateId attribute as your stream name and provide Kinesis Video Streams permissions on the stream using Amazon IoT. The steps for accomplishing this are similar to the ones previously outlined, with a few changes.

  • Modify the permissions policy to your IAM role (iam-permission-document.json) as follows:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kinesisvideo:DescribeStream", "kinesisvideo:PutMedia", "kinesisvideo:TagStream", "kinesisvideo:GetDataEndpoint" ], "Resource": "arn:aws:kinesisvideo:*:*:stream/${credentials-iot:AwsCertificateId}/*" } ] }
    Note

    The resource ARN uses certificate ID as the placeholder for the stream name. The IAM permission will work when you use the certificate ID as the stream name. Get the certificate ID from the certificate so that you can use that as stream name in the following describe stream API call.

    export CERTIFICATE_ID=`cat certificate | jq --raw-output '.certificateId'`
  • Verify this change using the Kinesis Video Streams describe-stream CLI command:

    AWS_ACCESS_KEY_ID=$(jq --raw-output '.credentials.accessKeyId' token.json) AWS_SECRET_ACCESS_KEY=$(jq --raw-output '.credentials.secretAccessKey' token.json) AWS_SESSION_TOKEN=$(jq --raw-output '.credentials.sessionToken' token.json) aws kinesisvideo describe-stream --stream-name ${CERTIFICATE_ID}
  • Pass the certificateId to the Amazon IoT credentials provider in the sample application in the Kinesis Video Streams C++ SDK:

    credential_provider = make_unique<IotCertCredentialProvider>(iot_get_credential_endpoint, cert_path, private_key_path, role_alias, ca_cert_path, certificateId);
    Note

    Note that you're passing the thingname to the Amazon IoT credentials provider. You can use getenv to pass the thingname to the demo application similar to passing the other Amazon IoT attributes. Use the certificate ID as the stream name in the command line parameters when you are running the sample application.

Use Amazon IoT credentials to stream to a hard-coded stream name

To represent your device (for example, your camera) through an Amazon IoT thing, but authorize streaming to a specific Amazon Kinesis video stream, provide Amazon Kinesis Video Streams permissions on the stream using Amazon IoT. The process is similar to the previous sections, with a few changes.

Modify the permissions policy to your IAM role (iam-permission-document.json) as follows:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kinesisvideo:DescribeStream", "kinesisvideo:PutMedia", "kinesisvideo:TagStream", "kinesisvideo:GetDataEndpoint" ], "Resource": "arn:aws:kinesisvideo:*:*:stream/YourStreamName/*" } ] }

Copy the X.509 certificate, private key, and CA certificate generated in the previous steps to your camera's file system.

Specify the paths for where these files are stored, the role alias name, the Amazon IoT thing name, and the Amazon IoT credentials endpoint for running the gst-launch-1.0 command or your sample application.

The following sample command uses Amazon IoT certificate authorization to send video to Amazon Kinesis Video Streams:

gst-launch-1.0 rtspsrc location=rtsp://YourCameraRtspUrl short-header=TRUE ! rtph264depay ! video/x-h264,format=avc,alignment=au ! h264parse ! kvssink stream-name="YourStreamName" aws-region="YourAWSRegion" iot-certificate="iot-certificate,endpoint=credential-account-specific-prefix.credentials.iot.aws-region.amazonaws.com,cert-path=/path/to/certificate.pem,key-path=/path/to/private.pem.key,ca-path=/path/to/cacert.pem,role-aliases=KvsCameraIoTRoleAlias,iot-thing-name=YourThingName"