|
| 1 | +# One-time field value saving for Silverstripe |
| 2 | + |
| 3 | +A Silverstripe module for storing private string values, optionally encrypted. |
| 4 | + |
| 5 | +To update the value, add the plain text secret to the relevant field and save the record, the old value will be overwritten. |
| 6 | + |
| 7 | +The stored value can be cleared using the supplied checkbox. |
| 8 | + |
| 9 | +## Installing |
| 10 | + |
| 11 | +The only supported method of installing this module is via composer: |
| 12 | + |
| 13 | +```shell |
| 14 | +composer require codem/silverstripe-onetime |
| 15 | +``` |
| 16 | + |
| 17 | +## Requirements |
| 18 | + |
| 19 | +[Per composer.json](./composer.json) |
| 20 | + |
| 21 | +## Configuration |
| 22 | + |
| 23 | +## Partial field value display |
| 24 | + |
| 25 | +Use the following configuration values with your project config to manage partial value display in supporting fields |
| 26 | + |
| 27 | +```yaml |
| 28 | +--- |
| 29 | +Name: app-onetime |
| 30 | +After: |
| 31 | + - '#onetime' |
| 32 | +--- |
| 33 | +Codem\OneTime\PartialValue: |
| 34 | + min_characters_replaced : 6 |
| 35 | + max_characters_replaced : 18 |
| 36 | + percent_cleared : 80 |
| 37 | + replacement_character: '*' |
| 38 | +``` |
| 39 | +
|
| 40 | +## Extension |
| 41 | +
|
| 42 | +In your site/module .yml configuration, assign the `HasSecrets` extension to the relevant DataObjects. Once applied and flushed, these dataobjects will be able to access the methods for encryption/decryption provided by the extension. |
| 43 | + |
| 44 | +```yaml |
| 45 | +MyOrg\MyDataObject: |
| 46 | + extensions: |
| 47 | + - 'Codem\OneTime\HasSecrets' |
| 48 | +MyOrg\AnotherDataObject: |
| 49 | + extensions: |
| 50 | + - 'Codem\OneTime\HasSecrets' |
| 51 | +``` |
| 52 | + |
| 53 | +In the relevant DataObjects, set up a configuration schema to mark certain fields as being handled by the module: |
| 54 | + |
| 55 | +```php |
| 56 | +<?php |
| 57 | +
|
| 58 | +namespace MyOrg; |
| 59 | +
|
| 60 | +use Codem\OneTime\PartialValue; |
| 61 | +use SilverStripe\ORM\DataObject; |
| 62 | +//... |
| 63 | +
|
| 64 | +class MyDataObject extends DataObject { |
| 65 | +
|
| 66 | + private static $onetime_field_schema = [ |
| 67 | +
|
| 68 | + // store a value locally |
| 69 | + 'TextFieldEmpty' => [ |
| 70 | + 'provider' => 'Local',// this field isn't encrypted |
| 71 | + 'partial' => false |
| 72 | + ], |
| 73 | +
|
| 74 | + // store the value encrypted with your KMS configuration |
| 75 | + 'TextFieldPartial' => [ |
| 76 | + 'provider' => 'AmazonKMS',// the stored value is encrypted using AWS KMS |
| 77 | + 'partial' => true, |
| 78 | + 'partial_filter' => PartialValue::FILTER_HIDE_MIDDLE // with a specific partial filter |
| 79 | + ], |
| 80 | + 'TextFieldPartialDefault' => [ |
| 81 | + 'provider' => 'Local', |
| 82 | + 'partial' => true // default partial value view |
| 83 | + ], |
| 84 | + 'TextareaFieldEmpty' => [ |
| 85 | + 'provider' => 'AmazonKMS', |
| 86 | + 'partial' => false // no partial value view |
| 87 | + ] |
| 88 | +
|
| 89 | + ]; |
| 90 | +
|
| 91 | + // etc |
| 92 | +} |
| 93 | +
|
| 94 | +``` |
| 95 | + |
| 96 | +## Providers |
| 97 | + |
| 98 | +There are two providers currently supported |
| 99 | + |
| 100 | +### Local |
| 101 | + |
| 102 | +The values are stored in the local database in plain text but are not displayed in the relevant fields. |
| 103 | + |
| 104 | +> :warning: This provider *only* helps to avoid users with certain CMS/Admin seeing secret values. |
| 105 | + |
| 106 | +### AmazonKMS |
| 107 | +The values are stored encrypted in the local database and are not shown in the relevant fields. Encryption and decryption is handled via the AWS client. |
| 108 | + |
| 109 | +You can use the decrypted values in your application, for instance submitting a consumer secret to an API. |
| 110 | + |
| 111 | +#### Configuration |
| 112 | + |
| 113 | +AmazonKMS requires an AWS Key, Secret Key, Key ID and AWS Region value to be available, add them to your site's configuration YML like so: |
| 114 | + |
| 115 | +```yaml |
| 116 | +Codem\OneTime\Provider\AmazonKMS: |
| 117 | + access_key: 'access_key' |
| 118 | + secret: 'secret' |
| 119 | + aws_region: 'an-aws-region' |
| 120 | + key_id: 'a-kms-keyid' |
| 121 | +``` |
| 122 | + |
| 123 | +**OR** |
| 124 | + |
| 125 | +You may also not provide the access_key & secret and instead rely on other authentication methods provided by AWS (e.g ~/.aws/credentials) |
| 126 | + |
| 127 | +The IAM user with the relevant access_key and secret must have encrypt/decrypt privileges set up. You should not use your AWS root/admin user for this. |
| 128 | + |
| 129 | +#### Encryption Context |
| 130 | + |
| 131 | +Encryption Context is optional and assists with logging of encrypt/decrypt requests. |
| 132 | + |
| 133 | +If you want to use this option, add it to the above configuration like so or in your environment: |
| 134 | + |
| 135 | +```yaml |
| 136 | +Codem\OneTime\Provider\AmazonKMS: |
| 137 | + access_key: 'access_key' |
| 138 | + secret: 'secret' |
| 139 | + aws_region: 'an-aws-region' |
| 140 | + key_id: 'a-kms-keyid' |
| 141 | + encryption_context: |
| 142 | + AContextKey: 'some_context_value' |
| 143 | +``` |
| 144 | + |
| 145 | +Read [Encryption Context documentation](https://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html) at AWS for more information. |
| 146 | + |
| 147 | +## Decrypting |
| 148 | +When you wish to get the field value back, simply call `decrypt()` on your DataObject. The argument is the field name. |
| 149 | + |
| 150 | +```php |
| 151 | +$instance = MyDataObject::get()->byId(1); |
| 152 | +$plaintext = $instance->decrypt('SomeFieldNameWithEncryptedValue'); |
| 153 | +``` |
| 154 | +You can then use that value in your application, e.g by passing it to an API. |
| 155 | + |
| 156 | +### Good-to-know |
| 157 | + |
| 158 | +### Visibility of secrets on entry |
| 159 | + |
| 160 | ++ Values you enter will be visible when entered into the field |
| 161 | ++ If your admin/website is not hosted over an HTTPS connection (!) data will be visible in transit |
| 162 | + |
| 163 | +### Field value truncation |
| 164 | + |
| 165 | +Encrypted values will be longer than the plain text version entered into the field. |
| 166 | + |
| 167 | +If your field is set as a Varchar field, you may experience truncation of the encrypted value when the database insert occurs. Rather than this module automatically changing your field types, it's highly recommended that you specify "Text" as the field type for the relevant fields. |
| 168 | + |
| 169 | +You can then use a ```TextField``` instead of a ```TextareaField``` in your DataObject's getCmsFields, if required. |
| 170 | + |
| 171 | +## LICENSE |
| 172 | + |
| 173 | +BSD-3-Clause |
| 174 | + |
| 175 | +## Maintainers |
| 176 | + |
| 177 | +Codem |
0 commit comments