Scripting Secrets with PowerShell and OneTimeSecret.com

In my day job, I often have to send out links to customers. These links have to be obscured as much as possible and it was getting painful manually sending each link using this service, so I decided to find a was of scripting secrets with PowerShell.

Scripting Secrets with PowerShell

Rather than sending the link directly from SharePoint or OneDrive, I need to use a service called OneTimeSecret.com.

So today, I wanted to show you the script I made to make this process as simple as running a PowerShell script.

You can also read this on Medium.com!

Introduction

I’ve mentioned that the links need to be obscured, but to prove it this is the workflow:

  • Upload password protected ZIP file to OneDrive
  • Create a OneDrive share with link a password
  • Create a OneTimeSecret.com secret with the OneDrive share link and password

You might call this overkill, but the idea is that people wouldn’t continuously have access to the OneDrive link to download whenever they wanted.

What I Was Doing Before?

Before scripting this process, I was manually visiting OneTimeSecret.com, entering in the OneDrive share link and the OneDrive share link password, and also adding a passphrase to the OneTimeSecret.com link.

I would then copy and paste the OneTimeSecret.com link and link passphrase over to the customer to download.

This was very manual and I knew there would have to be a better way!


Who Owns Microsoft?

Microsoft is one of the largest and most recognisable companies on the planet, operating in…

Read More

Broken Client Libraries

I tried using the PowerShell client library to make interacting with the OneTimeSecret.com API easier, but the library was completely broken and failed to load any of the commands. Often stating that it wasn’t found or a part of any modules.

Sad news, but I knew I could instead use the built in Invoke-RestMethod commandlet inside PowerShell to achieve the same thing but with more complex code.

Scripting Secrets with PowerShell

What I will do, is put my entire script below first and then explain it:

#Generate a random string to use as the Secret Link Password
$randomString = -join ((0..9) | Get-Random -Count 6)
$username = 'EMAIL_HERE'
$apiKey = 'API_KEY_HERE'
#Set the time to live to 3 days, or 259,200 seconds
$ttl = '259200'
#Set the secret content
$secretContent = @"
ONEDRIVE LINK HERE

ONEDRIVE LINK PASSWORD HERE
"@
$euApiUrl = 'https://eu.onetimesecret.com/api/v1/share'
$euSecretUrl = 'https://eu.onetimesecret.com/secret/'


# Encode the credentials
$credentials = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$username`:$apiKey"))

# Set up the body of the request
$body = @{
    secret = $secretContent
    ttl = $ttl
    passphrase = $randomString
}

# Make the POST request
$response = Invoke-RestMethod -Uri $euApiUrl `
                              -Method Post `
                              -Headers @{ Authorization = "Basic $credentials" } `
                              -Body $body


#Build the link to share with the customer
Write-Host "$($euSecretUrl)$($response.secret_key)"
Write-Host $randomString
Read-Host

Code Explanation

Awesome, now lets walk through the code!

Setup

First we setup the script, including:

  • Generating a random number passphrase for the OneTimeSecret link passphrase
  • Set the username and API key
  • Set the secret time-to-live (TTL)
  • Set the content required for the secret
  • Set the Secret URL and Secret API URL

All of that looks like this:

#Generate a random string to use as the Secret Link Password
$randomString = -join ((0..9) | Get-Random -Count 6)
$username = 'EMAIL_HERE'
$apiKey = 'API_KEY_HERE'
#Set the time to live to 3 days, or 259,200 seconds
$ttl = '259200'
#Set the secret content
$secretContent = @"
ONEDRIVE LINK HERE

ONEDRIVE LINK PASSWORD HERE
"@
$euApiUrl = 'https://eu.onetimesecret.com/api/v1/share'
$euSecretUrl = 'https://eu.onetimesecret.com/secret/'

Password & Splatting

Now we have the username and API key required, we can convert them into a base64 string to include in the API call. We also use splatting to build the body of the request:

# Encode the credentials
$credentials = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$username`:$apiKey"))

# Set up the body of the request
$body = @{
    secret = $secretContent
    ttl = $ttl
    passphrase = $randomString
}

I’ve talked about Splatting before, and it’s a really useful technique to make your scripts easier to build and to read. Basically, they look like hash tables which are super easy to read.

Execution & Output

Finally, we can run the API call and output the OneTimeSecret link and the passphrase generated inside the script:

# Make the POST request
$response = Invoke-RestMethod -Uri $euApiUrl `
                              -Method Post `
                              -Headers @{ Authorization = "Basic $credentials" } `
                              -Body $body


#Build the link to share with the customer
Write-Host "$($euSecretUrl)$($response.secret_key)"
Write-Host $randomString
Read-Host

Conclusion

And that’s everything you need to setup automatic secret sharing using OneTimeSecret.com.

If you have any questions, just leave them below in the comments and I’ll try my best to answer them. The documentation for this API is very good, the only thing that spoiled it for me were the client libraries. The PowerShell library hasn’t been updated in 4 years and is completely broken.

Thanks for reading! 🎉

email popup image
Mark Harwood
NEVER miss a blog post again! Subscribe for email notifications whenever a new post is live!
Subscribe
NEVER miss a blog post again! Subscribe for email notifications whenever a new post is live!
Fill Out This Form, And I Will Be In Touch Shortly
Contact form image
I'll Be In Touch Soon