Hi I want my automate functions to make some API calls and therefore I need a way to make a token available on the environment of the function. How can I do that with the C# sdk?
Hi @vwb
To allow users to add any data to an automation, we provide Function Inputs. In our C# example, simply add a property to the FunctionInputs
struct and it’ll then appear in the UI whenever you release your function.
As API tokens are sensitive values that are considered secrets and should be protected, we provide some additional safeguards to protect the data. These are encryption and redaction.
Currently in C# it’s possible to encrypt sensitive values, but it’s not as easy as I’d like to redact them. I will now go into detail on both encryption and redaction, and suggest some workarounds for redaction in C# below.
Encryption
Automate encrypts all input provided to an automation in the browser, and remains encrypted until either you request to view it, or it is inserted into a running automation. This is intended to keep secrets, such as API keys, secure.
If you create any property in the FunctionInputs
struct, see our C# example, it will handle the data securely.
All input is encrypted by default for all automations using any function.
Redaction
For items such as API keys, we also may wish to also redact the value so that it cannot be viewed again, either in the browser or via Automate’s API. When we try to view a redacted field, the data is replaced with an obscured value e.g. ******
, see screenshot below. That redacted data is only ever available in its unredacted form to a running automation.
When using Automate’s API directly, we define the function inputs as json schema. You can annotate the field in json schema with the writeOnly
property (see example at the bottom). The fields annotated with this property are then redacted.
For Python and C# we have SDKs to improve the experience, and convert native objects to json schema. Making a property writeOnly
, and thus redacted, is already possible with the Python SDK.
Unfortunately, I don’t think it’s currently implemented in the C# SDK. Speckle Sharp uses NewtonSoft’s schema generation tool to build the json schema from the C# FunctionInputs struct. The writeOnly
json schema property currently cannot be generated by the default Data Annotation attributes which are applied to the FunctionInputs struct.
If redaction is something you feel you need at the moment, I believe it might be possible to add the required functionality to Speckle Sharp by implementing a JSchemaGenerationProvider and an attribute, and amending how Speckle sharp builds the schema; suggestions and contributions are welcome!
Otherwise, you will have to create the Json schema file using a different method, perhaps manually writing it or using a json manipulation tool to insert the required property, and replace the auto-generated output in the GitHub Action.
An example json schema which causes input values to be redacted would look like the following:
{
$schema: 'https://json-schema.org/draft/2020-12/schema',
$id: 'https://example.com/apitoken.schema.json',
title: 'Accessing External API',
description: 'Provide an API token to access an external API',
type: 'object',
properties: {
redactedString: {
description: 'This is a secret string',
type: 'string',
writeOnly: true
},
redactedNumber: {
description: 'This is a secret number',
type: 'number',
writeOnly: true
},
notASecretString: {
description: 'This is not a secret string',
type: 'string'
},
notASecretNumber: {
description: 'This is not a secret number',
type: 'number'
}
},
required: [
'redactedNumber',
'notASecretString',
]
}
Hope this helps,
Iain
Thanks Iain, that’s very helpful. I’ll give it a try. As you say, it feels strange and confusing.
Maybe going from json → class instead of the opposite would give a better development experience, as the process would be the same for all sdks, something to think about.
Hey @vwb
a bit of heads up here, due to the amazing first day on the job efforts of @chuck, the C# sdk now supports this too.
We’ve considered also the json schema first approach. Our current reasoning is, that most function authors would want to stick to writing code in the language they know. Us using JSON schema in the background is in a way just an implementation detail, most users shouldn’t care about. JSON schema has its own gotchas and pitfalls with are in my view a bit harder to explain to AEC scripters.
As a personal preference, I’m also not a big fan of codegen sometimes being a big magic box that breaks in weird ways.
@vwb let me know what usecase we are not serving properly, we’d be happy to jump on that
Very nice. I’ll check that out!