Code Signing - CodeNotary - Code Notary



Knowing if your digital assets are safe to use will help you avoid complications from compromised or erroneous code running within your development, test, and production environments. This blog will walk you through the process of integrating blockchain-based code signing into your application using Golang.

For more on verifying with Golang, see our previous blog here.

Signing Assets

In order to have your application verify the assets you want to use, those assets will need to be signed and have their signatures stored on the blockchain. This way they can they can be referenced globally regardless of hosting service or storage location. However, before you can start signing assets, there are a few things you need to have in place.


First, you will need to create your CodeNotary account, which you can do here and see a video on how to do here. Once you have an account set up, you will have the ability to start signing assets with the CodeNotary vcn CLI tool. The next step is then to prepare your vcn configuration, which you can do simply by running vcn login. The first time the command is executed, a $HOME/.vcn folder will be created with the configuration and generate a user key for you. For more details, check out our GitHub user guide on configuration here. Also, you’ll want to be sure that the $HOME~/.vcn folder is accessible by the program you are coding.


Using Asset Signing in Your Go Code

We created vcn to be able to be utilized directly from within an individual application’s code structure. Extracting and placing a global verification checker like vcn directly into your project gives you the ability to configure it to run whenever you need or want it to do so.


To include asset signing in your code, use the snippet below:


package main

import (

func init() {
// Set ~/.vcn directory
if err := store.SetDefaultDir(); err != nil {
// Load the configuration
if err := store.LoadConfig(); err != nil {

// currentUser returns the current authenticated vcn user, if any,
otherwise an error is returned
func currentUser() (*api.User, error) {
email := store.Config().CurrentContext
if email == "" {
return nil, fmt.Errorf("no user has been set for current context")
   u := api.NewUser(email)
return u, nil

func main() {
passphrase := ""
// Get the current user
user, err := currentUser()
if err != nil {
  // Create a fake asset
asset := api.Artifact{
Name: "",
Hash: "",
Size: 11, // a size > 0 is required
  verification, err := user.Sign(
user.DefaultKey(), // get and use the default key, optionally another key can be used
meta.StatusTrusted,     // other status (meta.StatusUntrusted, meta.StatusUnsupported) can be used too
meta.VisibilityPrivate, // or meta.VisibilityPublic
if err != nil {
  fmt.Println("Asset has been successfully signed with Status: ", meta.StatusName(verification.Status))


How It Works



The package gives you access to all the low-level functions.


The pulls in the vcn API and allows you to write directly to the blockchain.


The store.SetDefaultDir then sets your default directory for where you will store your asset signatures locally. Then the store.LoadConfig will set up the configuration locally and enable you to write to the blockchain.



Next, you will need to create the function currentUser to validate the current vcn user exists in the system. If the information entered is correct, then the user is allowed to proceed, otherwise, an error is returned.



After setting up a path to check your user information is stored within the system, you need to create a function for allowing you to enter your passphrase, which will enable you to sign assets and have their hashes written to the blockchain. The vcn application will then match the previously entered currentUser to the entered passphrase. If successful, the system will allow you to proceed. If not, an error will be returned.


The next step is to choose an asset you want to load for signing later. (You can also create a fake asset if you are just testing out the functionality.) But first, you need to set up output fields for correctly storing the name, hash, and size of a newly signed asset for the api.Artifact function to slot created data into.


You can read more about all the fields in our Go doc at



Once your fields have been set up to store your signing artifacts, you need to get the key the system generated for you the first time you signed in using vcn login and which is stored, by default, in the ~/.vcn folder. (Optionally, you can choose to use another key for signing if you wish, though you will have to designate it specifically.) After you have told the system which key to use in the signing process, you need to specify the passphrase that will allow your key to be used to sign an asset.


If everything is successful, the system will append the designated meta.Status and meta.Visibility to your signature. The output you should see is the printed line as seen in the example below:


Asset has been successfully signed with Status: TRUSTED



Inserting the ability for your application to sign the digital assets you create or use allows you to benefit from the immutability of the blockchain and rest assured your code, components, applications, and more are just as safe as the way you left them.


Information on our entire vcn project can be found in our GitHub repository, which you can check out by following the link below.



Take Me to GitHub Repo


Learn More at

Metrics and Logs

(formerly, Opvizor Performance Analyzer)

VMware vSphere & Cloud

Monitor and Analyze Performance and Log files:
Performance monitoring for your systems and applications with log analysis (tamperproof using immudb) and license compliance (RedHat, Oracle, SAP and more) in one virtual appliance!

Subscribe to Our Newsletter

Get the latest product updates, company news, and special offers delivered right to your inbox.

Subscribe to our newsletter

Use Case - Tamper-resistant Clinical Trials


Blockchain PoCs were unsuccessful due to complexity and lack of developers.

Still the goal of data immutability as well as client verification is a crucial. Furthermore, the system needs to be easy to use and operate (allowing backup, maintenance windows aso.).


immudb is running in different datacenters across the globe. All clinical trial information is stored in immudb either as transactions or the pdf documents as a whole.

Having that single source of truth with versioned, timestamped, and cryptographically verifiable records, enables a whole new way of transparency and trust.

Use Case - Finance


Store the source data, the decision and the rule base for financial support from governments timestamped, verifiable.

A very important functionality is the ability to compare the historic decision (based on the past rulebase) with the rulebase at a different date. Fully cryptographic verifiable Time Travel queries are required to be able to achieve that comparison.


While the source data, rulebase and the documented decision are stored in verifiable Blobs in immudb, the transaction is stored using the relational layer of immudb.

That allows the use of immudb’s time travel capabilities to retrieve verified historic data and recalculate with the most recent rulebase.

Use Case - eCommerce and NFT marketplace


No matter if it’s an eCommerce platform or NFT marketplace, the goals are similar:

  • High amount of transactions (potentially millions a second)
  • Ability to read and write multiple records within one transaction
  • prevent overwrite or updates on transactions
  • comply with regulations (PCI, GDPR, …)


immudb is typically scaled out using Hyperscaler (i. e. AWS, Google Cloud, Microsoft Azure) distributed across the Globe. Auditors are also distributed to track the verification proof over time. Additionally, the shop or marketplace applications store immudb cryptographic state information. That high level of integrity and tamper-evidence while maintaining a very high transaction speed is key for companies to chose immudb.

Use Case - IoT Sensor Data


IoT sensor data received by devices collecting environment data needs to be stored locally in a cryptographically verifiable manner until the data is transferred to a central datacenter. The data integrity needs to be verifiable at any given point in time and while in transit.


immudb runs embedded on the IoT device itself and is consistently audited by external probes. The data transfer to audit is minimal and works even with minimum bandwidth and unreliable connections.

Whenever the IoT devices are connected to a high bandwidth, the data transfer happens to a data center (large immudb deployment) and the source and destination date integrity is fully verified.

Use Case - DevOps Evidence


CI/CD and application build logs need to be stored auditable and tamper-evident.
A very high Performance is required as the system should not slow down any build process.
Scalability is key as billions of artifacts are expected within the next years.
Next to a possibility of integrity validation, data needs to be retrievable by pipeline job id or digital asset checksum.


As part of the CI/CD audit functionality, data is stored within immudb using the Key/Value functionality. Key is either the CI/CD job id (i. e. Jenkins or GitLab) or the checksum of the resulting build or container image.

White Paper — Registration

We will also send you the research paper
via email.

CodeNotary — Webinar

White Paper — Registration

Please let us know where we can send the whitepaper on CodeNotary Trusted Software Supply Chain. 

Become a partner

Start Your Trial

Please enter contact information to receive an email with the virtual appliance download instructions.

Start Free Trial

Please enter contact information to receive an email with the free trial details.