# Best practice for handling private keys in GitHub actions

**URL:** <https://forum.dfinity.org/t/best-practice-for-handling-private-keys-in-github-actions/64439>\
**Category:** Command Line Tools\
**Created:** [February 20, 2026, 12:05pm UTC](https://forum.dfinity.org/t/best-practice-for-handling-private-keys-in-github-actions/64439 "2026-02-20T12:05:43Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattigrthr](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/mattigrthr/32/35058_2.png) [@mattigrthr](https://forum.dfinity.org/u/mattigrthr)\
**Post date:** [February 20, 2026, 12:05pm UTC](https://forum.dfinity.org/t/best-practice-for-handling-private-keys-in-github-actions/64439/1 "2026-02-20T12:05:43Z")

</div>

Hello,

I’ve been using the `icp cli` these past days to deploy my canisters. These are actually my first deploys so I have not much context of how things have been done with `dfx`.

I was starting to set up CD jobs on GitHub. As I understand, we have to import our identity before deploying. I set my private key as a secret on GitHub and then “echo” it into a `.pem` which I then use for the `icp identity import`.

I see that there are different storage options to save the key. Initially, I tried the `password` approach.

However, I see that for the DFINITY portal, you are using the `plaintext` approach.

> <https://github.com/dfinity/portal/blob/58cdc5268431f4728346ae1374101471e0deb5a8/.github/workflows/cd.yml#L47>

I was wondering what the recommended approach and best practice is here.

Is it considered safe to store it as plain text since the action’s environment is ephemeral?

@marc0olo I asked this in the chat in yesterday’s CLI session and you mentioned you can loop some people in here.

Apart from that, the deployment using the cli is very intuitive. 👌🏽

Cheers!

---

<div class="post-metadata">

**Author:** ![Vivienne](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/vivienne/32/29170_2.png) [@Vivienne](https://forum.dfinity.org/u/Vivienne)\
**Post date:** [February 20, 2026, 1:26pm UTC](https://forum.dfinity.org/t/best-practice-for-handling-private-keys-in-github-actions/64439/2 "2026-02-20T13:26:07Z")

</div>

`icp-cli` supports three types of identities right now: plaintext, password protected file, and HSM.

HSMs are the most secure since they don’t give out the key, but they are pretty hard to automate, especially on CI.

If you use something like GH runners, plaintex and password protected identities look almost identically secure to me. GH controls the full workflow, including all secrets. If they wanted to crack a password protected identity they can do so easily, since you need to access the password in the CD job too.

It all boils down to trust. If you do not accidentally print the identity where it’s visible to everyone, GH has full access to everything that happens on their runners. If you trust them, I don’t see a big difference between identities with and without passwords and would consider both roughly similarly safe. If you don’t trust them, you’re probably better off with a different CD setup, or a HSM
