Signing with PKCS#11
CK_OBJECT_HANDLE hPrivKey = find_key_by_label(hSession, "ca-signing-key");
CK_MECHANISM mechanism = { CKM_ECDSA, NULL_PTR, 0 };
C_SignInit(hSession, &mechanism, hPrivKey);
CK_BYTE digest[32];
sha256(data, dataLen, digest);
CK_BYTE signature[64];
CK_ULONG sigLen = sizeof(signature);
C_Sign(hSession, digest, sizeof(digest), signature, &sigLen);
For CA signing: the CA software (SPIRE, EJBCA, your code) calls C_Sign with the CSR digest.
The HSM performs the signing. The private key never touches RAM.