Logo

MacStadium Blog

Orka Tips and Tricks - Secret Management

We get asked a lot about how to store secrets inside of Orka. It’s not always needed, but if you want to, we have a step-by-step guide for building your own custom solution.

One of the most common questions we get asked at MacStadium is - how to store secrets inside Orka? And why would you need to store secrets inside of Orka?

From our experience, teams usually use Orka VMs as build executors and want to pass secrets to those VMs so they can access a protected resource. But while you might not need to store secrets inside of Orka, you may want to. Let’s discuss both options and give you a rundown of how you can make secrets with Orka work.

You may not need to store secrets inside Orka.

Storing secrets inside Orka isn’t always necessary. Modern build systems like JenkinsGitLab CIGitHub Actions, and many more allow the passing of secrets from the build server to the build executors.
In cases like this, secrets are not stored inside the Orka cluster; they’re only passed through to the VMs during build time if needed.

Build a Custom Solution on Top of Orka

A custom solution! Because each team is unique, a special solution may be required. And while Orka does not provide a secret management solution, it provides the building blocks to create one.

Let’s go over a simplified secret management tool that can be built on top of Orka.

Technical Design

This solution consists of three parts:

  1. Secret store - the service used to store secrets
  2. Secret provider - the service used to provide secrets
  3. Secret consumer - an Orka VM that uses the provider to consume secrets

Implementation

Prerequisites

Our first step is to create a kube account inside Orka. We won’t be going over that for our simplified version, but if you need more information on how to do that, see here.

Secret Store

To create the secret store, we are going to use Kubernetes. Orka runs on top of Kubernetes, and we can leverage Kubernetes secret resources. To deploy a Kubernetes secret:

1. Create a file called secret.yml with the following contents:

apiVersion: v1
kind: Secret
metadata:
 name: my-secret
type: Opaque
data:
 MY_SECRET: <secret_base_64></secret_base_64>

Where <secret_base_64> is the base64 encoding of the secret. </secret_base_64>

2. Run kubectl apply -f secret.yml
After successfully running the command, the secret is stored inside Kubernetes.

Secret Provider

The next step is to create a service that reads Kubernetes secrets and provides them to consumers.
For this, we’ll:

1. Create a sample Node.js express app:

"use strict";

const express = require("express");

const PORT = 8080;
const HOST = "0.0.0.0";

const app = express();
app.get("/secret", async (req, res) => {
 res.send(processj.env.ENV_SECRET);
});

app.listen(PORT, HOST);

The application listens on port 8080 and returns the environment variable called MY_SECRET.

2. Package the application in a Docker file:

FROM node:12.18.3

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080
CMD [ "node", "server.js" ]

3. Run docker build -t <tag> . to create a Docker image</tag>

4. Run docker push <tag> to push the tag to a public Docker registry. </tag>

Next, we’ll deploy the service inside Kubernetes and pass the secret we created in the previous step as an environment variable to the Node.js express app.

To do that, we’ll:

1. Create a file called service.yml with the following contents:

apiVersion: v1
kind: Service
metadata:
 name: secret-app
 labels:
   app: secret-app
spec:
 ports:
   - port: 80
     targetPort: 8080
 selector:
   app: secret-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: secret-app
 labels:
   app: secret-app
spec:
 replicas: 1
 selector:
   matchLabels:
     app: secret-app
 template:
   metadata:
     labels:
       app: secret-app
   spec:
     containers:
       - name: secret-container
         image: <tag></tag>
         imagePullPolicy: Always
         ports:
           - containerPort: 8080
         env:
           - name: ENV_SECRET
             valueFrom:
               secretKeyRef:
                 name: my-secret
                 key: MY_SECRET

This deployment uses the tag we pushed in the previous step and passes the secret we defined as an environment variable to the Node.js service.

2. Run kubectl apply -f service.yml to deploy the service in Kubernetes.

3. You can now access the service using its A record: secret-app.sandbox.svc.cluster.local from within the cluster.

Secret Consumer

The final step is to deploy an Orka VM and run curl -sb -H "Accept: application/json" secret-app.sandbox.svc.cluster.local/secret. The command returns the stored secret.

Of course, this is just an example of a custom solution that could work for you or your team. It can be easily changed or extended to support authentication and authorization to meet your team’s specific needs.

Conclusion

While storing secrets inside Orka may not always be needed, your team may have a use case that calls for it. Orka provides the building blocks to create one that matches your requirements. Not an Orka user? Try Orka for yourself or talk to one of our sales engineers today.

Logo

Orka, Orka Workspace and Orka Pulse are trademarks of MacStadium, Inc. Apple, Mac, Mac mini, Mac Pro, Mac Studio, and macOS are trademarks of Apple Inc. The names and logos of third-party products and companies shown on the website are the property of their respective owners and may also be trademarked.

©2023 MacStadium, Inc. is a U.S. corporation headquartered at 3525 Piedmont Road, NE, Building 7, Suite 700, Atlanta, GA 30305. MacStadium, Ltd. is registered in Ireland, company no. 562354.