title: Creating AWS IoT "things" with policies and certificates on-the-fly
body: <p>I am using NodeJS along with <a href="http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/" rel="nofollow noreferrer">AWS JS SDK</a> and <a href="https://github.com/aws/aws-iot-device-sdk-js" rel="nofollow noreferrer">AWS IoT Device JS SDK</a> in order to automatically create a new thing and assign certificates and policies to it once it connects to my server.</p>
  
  <p>I was following <a href="https://aws.amazon.com/blogs/iot/just-in-time-registration-of-device-certificates-on-aws-iot/" rel="nofollow noreferrer">"Just-in-Time Registration" article</a> in order to create, register and activate my CA certificate. As far as I can tell, the CA certificate is successfully added to AWS IoT, activated and enabled for auto-registration.</p>
  
  <p>What I don't understand is how is this step performed (quote from mentioned article):</p>
  
  <blockquote>
    <p>When a device attempts to connect with an X.509 certificate that is not known to AWS IoT but was signed by a CA that was registered with AWS IoT, the device certificate will be auto-registered by AWS IoT in a new PENDING_ACTIVATION state.</p>
  </blockquote>
  
  <p>How do I make an "attempt" to connect? Since I was using <code>aws-iot-device-sdk-js</code> SDK, with manually created certificates, I was usually connecting my device like this:</p>
  
  <pre><code>const device = deviceModule.device({
    host: 'myendpoint.iot.us-east-1.amazonaws.com',
    region: 'us-east-1',
    keyPath: `certs/${deviceID}.key`,
    certPath: `certs/${deviceID}.pem`,
    caPath: 'certs/rootCA.pem',
    clientId: deviceID,
    baseReconnectTimeMs: 4000,
    keepalive: 30,
    protocol: 'mqtts',
  });
  </code></pre>
  
  <p>But now I don't have certificate and key to include in <code>keyPath</code> and <code>certPath</code> and I cannot instantiate my device without it.</p>
  
  <p>I tried to create certificates myself, using <a href="http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Iot.html#createKeysAndCertificate-property" rel="nofollow noreferrer"><code>createKeysAndCertificate()</code></a> from AWS SDK, saving them to disk, attaching a policy manually, attaching a principal manually even tried to mark certificate as "active" manually, something along these lines:</p>
  
  <pre><code>iot.createThing({ thingName: deviceID }, (err, d) =&gt; {
    if (err) {
      console.log(err);
    } else {
      allThings[d.thingName] = d;
      iot.createKeysAndCertificate({ setAsActive: true }, (e, c) =&gt; {
        if (e) {
          console.log(e);
        } else {
          fs.writeFile(`certs/${deviceID}.pem`, c.certificatePem, (ef, f) =&gt; {
            if (ef) throw ef;
          });
          fs.writeFile(`certs/${deviceID}.key`, c.keyPair.PrivateKey, (ef, f) =&gt; {
            if (ef) throw ef;
          });
          iot.attachPrincipalPolicy({
            policyName: 'my-testing-policy',
            principal: c.certificateArn,
          }, (ee, cc) =&gt; {
            if (ee) {
              console.log(ee);
            } else {
              iot.attachThingPrincipal({
                principal: c.certificateArn,
                thingName: deviceID,
              }, (prerr, prdata) =&gt; {
                if (prerr) {
                  console.log(prerr);
                } else {
                  iot.acceptCertificateTransfer({
                    certificateId: c.certificateId,
                    setAsActive: true,
                  }, (ce, cd) =&gt; {
                    if (err) {
                      console.log(err);
                    } else {
                      console.log('cert activated.');
                    }
                  });
                }
              });
            }
          });
        }
      });
    }
  });
  </code></pre>
  
  <p>But after all this, when I try to publish something I am presented with an error:</p>
  
  <pre><code>Error: unable to get local issuer certificate
      at Error (native)
      at TLSSocket.&lt;anonymous&gt; (_tls_wrap.js:1092:38)
      at emitNone (events.js:86:13)
      at TLSSocket.emit (events.js:185:7)
      at TLSSocket._finishInit (_tls_wrap.js:610:8)
      at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:440:38)
  </code></pre>
  
  <p>I also tried to subscribe to specific topic, as mentioned in the same article above, <code>aws/events/certificates/registered/e3f0a30...</code> but I've never seen a single message on that topic...</p>
  
  <p>What am I missing here? How do I trigger device certificate and private key generation properly just by using my Just-in-Time certificate?</p>