<p>I was able to manually create a certificate:</p>
<ol>
<li>I created a csr file</li>
<li>I created and applied a <code>CertificateSigningRequest</code> k8s resource</li>
<li>I approved the request using</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>kubectl certificate approve &lt;name&gt;
</code></pre>
<ol start="4">
<li>I extracted the certificate from the <code>CertificateSigningRequest</code>'s <code>status.certificate</code> field.</li>
</ol>
<p>Now I want to repeat the process programmatically. I'm using the <code>@kubernetes/client-node</code> npm package for this purpose.</p>
<p>I'm able to create and apply the <code>CertificateSigningRequest</code> resource:</p>
<pre class="lang-js prettyprint-override"><code>const csrResource = await adminCertApi.createCertificateSigningRequest({
    metadata: {
        name: 'my.email@my.company.com',
    },
    spec: {
        request: csrBase64,
        signerName: 'kubernetes.io/kube-apiserver-client',
        usages: [
            'client auth'
        ],
    },
});
</code></pre>
<p>But then I get stuck trying to approve the request (trying to follow the <a href="https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#approval-rejection-api-client" rel="nofollow noreferrer">documentation</a>). I tried several variations that look like this:</p>
<pre class="lang-js prettyprint-override"><code>csrResource.body.status.conditions = [
    {
        message: 'Approved by CWAdmin GraphQL Lambda function',
        reason: 'ApprovedByCWAdmin',
        type: 'Approved',
    }
];
const response = await adminCertApi.patchCertificateSigningRequest('my.email@my.company.com', csrResource.body, undefined, undefined, undefined, undefined, { headers: { 'Content-Type': 'application/strategic-merge-patch+json' } });

</code></pre>
<p>Unfortunately, this does not update the <code>status.conditions</code> field. Even if it did, what triggers the signing of the certificate? The documentation states that the <code>kube-controller-manager</code> never auto-approves requests of type <code>kubernetes.io/kube-apiserver-client</code>.</p>
<p>In other words, what is the programmatic equivalent of <code>kubectl certificate approve</code>?</p>

Perspectivus
<p>I found this bit of <a href="https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/1513-certificate-signing-request/README.md#api-changes-between-v1beta1-and-v1" rel="nofollow noreferrer">documentation</a> that helped me solve the issue:</p>
<blockquote>
<ul>
<li><code>status</code> is required and must be <code>True</code>, <code>False</code>, or <code>Unknown</code></li>
<li><code>Approved</code>/<code>Denied</code> conditions can only be set via the <code>/approval</code> subresource</li>
</ul>
</blockquote>
<p>So I added the <code>status</code> field to the condition and changed the API call to <code>patchCertificateSigningRequestApproval</code>.</p>
<p>The working code now looks like this:</p>
<pre class="lang-js prettyprint-override"><code>const body = {
    status: {
        conditions: [
            {
                message: 'Approved by CWAdmin GraphQL Lambda function',
                reason: 'ApprovedByCWAdmin',
                type: 'Approved',
                status: 'True',
            }
        ]
    }
};

const response = await adminCertApi.patchCertificateSigningRequestApproval('my.email@my.company.com', body, undefined, undefined, undefined, undefined, { headers: { 'Content-Type': 'application/strategic-merge-patch+json' } });

</code></pre>
