Skip to content

Creating a Rekeyable Object Provider

Anthony Turner edited this page Apr 27, 2020 · 1 revision

About Rekeyable Object Providers

A Rekeyable Object Provider is a provider which contains logic to regenerate a key, token, or secret for a given service or object. The RKO Provider understands what "secure" entails in the context of different Rekeyable Objects, allowing risks to be effectively generated and scored as a part of the approval process.

[Provider(Name = "My First RKO Provider",
            IconClass = "fa fa-gears",
            Description = "This is the first RKO provider I wrote!")]
[ProviderImage(MY_PROVIDERS_SVG_LOGO_STRING)]
public class MyFirstRKOProvider : RekeyableObjectProvider<MyFirstProviderConfiguration>
{
    public override Task<RegeneratedSecret> GetSecretToUseDuringRekeying()
    {
        // This method is called prior to rekeying, to get a secret to use temporarily while the rekeying is taking place.
        // This is to facilitate zero-downtime deployments by providing a bridge to the new, final key.

        return Task.FromResult(new RegeneratedSecret()
        {
            Expiry = DateTimeOffset.Now + TimeSpan.FromMinutes(10),
            UserHint = Configuration.UserHint,
            NewSecretValue = "iWillOnlyBeUsedTemporarily"
        })
    }

    public override Task<RegeneratedSecret> Rekey(TimeSpan requestedValidPeriod)
    {
        // This method is called after all Application Lifecycle Providers have completed "BeforeRekeying()"
        // It should not complete the Task until the service/object has completed the Rekeying operation.
        // It is expected that the consuming application will be able to use the new key at the moment this Task completes.

        return Task.FromResult(new RegeneratedSecret()
        {
            Expiry = DateTimeOffset.Now + requestedValidPeriod,
            UserHint = Configuration.UserHint,
            NewSecretValue = "newValidSecretValue"
        });
    }

    public override Task OnConsumingApplicationSwapped()
    {
        // This optional method is called after all Application Lifecycle Providers have had their GeneratedSecrets committed to their applications.

        return Task.FromResult(true);
    }

    public override Task Test()
    {
        // This optional method is called before any action, to ensure the credentials provided are sufficient to perform
        //   the requested action. If not specified, the test will always pass.

        return Task.FromResult(true);
    }

    public override IList<RiskyConfigurationItem> GetRisks(TimeSpan requestedValidPeriod)
    {
        // This optional method is called to assess the Provider as-configured for risks, when taking into account the requested
        //   period of validity for the ManagedSecret. When implemented, GetRisks methods should always call each other as well as
        //   the GetRisks method of the ProviderConfiguration structure for this Provider.

        // When not implemented, GetRisks(TimeSpan) calls GetRisks(), which calls Configuration.GetRiskyConfigurations().
        // These three methods together should enumerate any risky configurations.

        return GetRisks();
    }

    public override IList<RiskyConfigurationItem> GetRisks()
    {
        // This optional method is called to assess the Provider as-configured for risks, independent of the configuration of the 
        //   ManagedSecret. When implemented, GetRisks methods should always call each other as well as the GetRisks method of the
        //   ProviderConfiguration structure for this Provider.

        // When not implemented, GetRisks(TimeSpan) calls GetRisks(), which calls Configuration.GetRiskyConfigurations().
        // These three methods together should enumerate any risky configurations.

        return new List<RiskyConfigurationItem>();
    }

    // This method should be a human readable sentence-or-two description of what the Provider does.
    public override string GetDescription() => "This provider is my first RKO provider, and it does some things!";
}

Clone this wiki locally