Difference between revisions of "Best Practice and Example Trust Registry"
(→Questions and Answers for Designers and Developers) |
(→Model of the User in the Database) |
||
(33 intermediate revisions by the same user not shown) | |||
Line 62: | Line 62: | ||
For more information see this page on [[User Private Information]]. | For more information see this page on [[User Private Information]]. | ||
====Model of the User in the Database==== | ====Model of the User in the Database==== | ||
− | The goal of the data collected (as a [[User Object]]) about the individual and organizational users is to model the [[User]]s that are served by the web site with [[User Private Information]] intended for release by the users. Field names taken from other standards, like Open ID Connect, are highlighted in blue. This is a practice where the RP can determine the category tag used on each data field in advance based on the needs of the site. It may be necessary for the RP get user consent which requires that some fields are dynamically tagged based on user intent or user actions. In those cases | + | The goal of the data collected (as a [[User Object]]) about the individual and organizational users is to model the [[User]]s that are served by the web site with [[User Private Information]] intended for release by the users. Field names taken from other standards, like Open ID Connect, are highlighted in blue. This is a practice where the RP can determine the category tag used on each data field in advance based on the needs of the site. It may be necessary for the RP get user consent which requires that some fields are dynamically tagged based on user intent or user actions. In those cases a more complex design might be required. For example a deletion date may need to be associated with some fields. |
{|border="1" padding="2" width="799px" | {|border="1" padding="2" width="799px" | ||
Line 73: | Line 73: | ||
|Type || numeric || 1 || (1)individual, (2)organization (can be a parent), (3) pseudonym (avoid any linkage) | |Type || numeric || 1 || (1)individual, (2)organization (can be a parent), (3) pseudonym (avoid any linkage) | ||
|- | |- | ||
− | |Parent || link (exactly one) || 2 || link to an organization in this db, the default parent is the | + | |Parent || link (exactly one) || 2 || link to an organization in this db, the default parent is the federation root entry |
|- | |- | ||
| Member || code || 1 || 0=none, 1= member in good standing, 2=candidate for membership, 3=suspended or resigned | | Member || code || 1 || 0=none, 1= member in good standing, 2=candidate for membership, 3=suspended or resigned | ||
Line 132: | Line 132: | ||
<blockquote>The CA SHALL implement physical and logical safeguards to prevent unauthorized certificate issuance. | <blockquote>The CA SHALL implement physical and logical safeguards to prevent unauthorized certificate issuance. | ||
Protection of the CA Private Key outside the validated system or device specified above MUST consist of physical security, encryption, or a combination of both, implemented in a manner that prevents disclosure of the CA Private Key. The CA SHALL encrypt its Private Key with an algorithm and key-length that, according to the state of the art, are capable of withstanding cryptanalytic attacks for the residual life of the encrypted key or key part.</blockquote> | Protection of the CA Private Key outside the validated system or device specified above MUST consist of physical security, encryption, or a combination of both, implemented in a manner that prevents disclosure of the CA Private Key. The CA SHALL encrypt its Private Key with an algorithm and key-length that, according to the state of the art, are capable of withstanding cryptanalytic attacks for the residual life of the encrypted key or key part.</blockquote> | ||
+ | |||
+ | Best Practice would ensure that not access was granted to any application running on the front end server accessible from external web addresses. The processes that can access the signing or decryption keys should only be accessed on internal networks preferably as micro-services. This implies that the ssl certs and keys used on the front web connections are not adequate for signing of protected documents. Decryption services may still be accessed from front end services unless the keys are shared with signing services, which is probably not the best design. | ||
+ | |||
+ | Best Practice for micro-services in internal, hardware protection of keys and self-signed certs that are included in the cert:\localmachine\root storage locations. | ||
+ | * [https://docs.microsoft.com/en-us/windows/win32/seccng/key-storage-and-retrieval CNG Key Storage and Retrieval] in Windows. | ||
===Discovery Endpoint=== | ===Discovery Endpoint=== | ||
Line 144: | Line 149: | ||
Set up goals and start to build examples and best practices for all of the roles in an ID ecosystem. | Set up goals and start to build examples and best practices for all of the roles in an ID ecosystem. | ||
+ | # separate front end in iis from registry server in Kestrel for api processing | ||
+ | #put simpleservice for gPRC in same deploy package as registry server | ||
+ | # if the error "The library 'hostpolicy.dll' required to execute the application was not found" comes the following fix worked | ||
+ | <pre> | ||
+ | PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1> dir C:\Users\rp_to_000\Documents\TopCat | ||
+ | \Repos\TrustRegistry3\SimpleService\bin\Debug\netcoreapp3.1\sim*config*.json | ||
+ | |||
+ | Directory: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\SimpleService\bin\Debug\netcoreapp3.1 | ||
+ | |||
+ | Mode LastWriteTime Length Name | ||
+ | ---- ------------- ------ ---- | ||
+ | -a---- 2020-06-07 4:53 PM 284 SimpleService.runtimeconfig.dev.json | ||
+ | -a---- 2020-06-07 4:53 PM 288 SimpleService.runtimeconfig.json | ||
+ | |||
+ | PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1> copy C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\SimpleService\bin\Debug\netcoreapp3.1\sim*config*.json . | ||
+ | PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1> .\SimpleService.exe | ||
+ | Hosting environment: Development | ||
+ | Content root path: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1\ | ||
+ | Now listening on: https://localhost:5033 | ||
+ | Application started. Press Ctrl+C to shut down. | ||
+ | </pre> | ||
+ | |||
+ | ===Trust Registry Build and Deploy=== | ||
+ | This is the front end process designed to run under IIS. | ||
+ | * Windows Registry settings to enable a windows event log for this application | ||
+ | * Note that these are in the local machine branch and so must be run with admin creds. | ||
+ | C:\certs> reg import .\trustregistry.reg | ||
+ | or | ||
+ | C:\certs> regedit /s .\trustregistry.reg | ||
+ | Where the following content is in that file: | ||
+ | <pre> | ||
+ | Windows Registry Editor Version 5.00 | ||
+ | |||
+ | [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\TrustRegistry] | ||
+ | "EventMessageFile"=hex(2):43,00,3a,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,\ | ||
+ | 00,73,00,5c,00,4d,00,69,00,63,00,72,00,6f,00,73,00,6f,00,66,00,74,00,2e,00,\ | ||
+ | 4e,00,45,00,54,00,5c,00,46,00,72,00,61,00,6d,00,65,00,77,00,6f,00,72,00,6b,\ | ||
+ | 00,36,00,34,00,5c,00,76,00,34,00,2e,00,30,00,2e,00,33,00,30,00,33,00,31,00,\ | ||
+ | 39,00,5c,00,45,00,76,00,65,00,6e,00,74,00,4c,00,6f,00,67,00,4d,00,65,00,73,\ | ||
+ | 00,73,00,61,00,67,00,65,00,73,00,2e,00,64,00,6c,00,6c,00,00,00 | ||
+ | </pre> | ||
+ | |||
+ | ===Registry Server Build and Deploy=== | ||
+ | This is the API process designed to run under Kestrel so that it can support HTTP/2 access to the Simple Service. | ||
+ | |||
+ | It is designed for dotnetcore 3.1 running as a windows service. This means that it will be started from C:/Windows/System32, which will set Content Root incorrectly if the createdefaultbuilder method is used in prograam.cs. | ||
+ | |||
+ | * [https://dotnetcoretutorials.com/2019/07/31/what-does-the-createdefaultbuilder-method-do-in-asp-net-core/ describes the createdefaultbuilder method] | ||
+ | |||
+ | In this example the date should be the current date. | ||
+ | <pre> | ||
+ | cd C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer | ||
+ | dotnet publish | ||
+ | .\private\CleanUp.ps1 | ||
+ | .\private\rs-deploy.ps1 | ||
+ | PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\private> dir *200618* | ||
+ | |||
+ | Directory: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\private | ||
+ | |||
+ | Mode LastWriteTime Length Name | ||
+ | ---- ------------- ------ ---- | ||
+ | -a---- 2020-06-18 4:13 PM 4890460 registryserver-app-20061816.zip | ||
+ | -a---- 2020-06-18 4:13 PM 4869241 registryserver-deploy-20061816.zip | ||
+ | |||
+ | |||
+ | go to | ||
+ | Amazon S3/elasticbeanstalk-us-east-2-522802581903/registryserver | ||
+ | upload | ||
+ | registryserver-app-20061816.zip | ||
+ | make sure that the upload completed successfully - retry if not | ||
+ | make file public | ||
+ | copy the url | ||
+ | go to | ||
+ | AWS system manager> session manager | ||
+ | click start session | ||
+ | select us-east-2 | ||
+ | click start session | ||
− | + | S C:\Windows\system32> cd C:\inetpub\AspNetCoreWebApps\ | |
− | + | PS C:\inetpub\AspNetCoreWebApps> dir | |
+ | |||
+ | |||
+ | Directory: C:\inetpub\AspNetCoreWebApps | ||
+ | |||
+ | |||
+ | Mode LastWriteTime Length Name | ||
+ | ---- ------------- ------ ---- | ||
+ | d----- 6/18/2020 4:23 AM app | ||
+ | d----- 6/16/2020 9:21 PM regsvr | ||
+ | d----- 6/9/2020 9:08 PM regsvr1 | ||
+ | d----- 6/15/2020 8:39 PM regsvr2 | ||
+ | |||
+ | PS C:\inetpub\AspNetCoreWebApps> ren .\regsvr\ .\regsvr-200616 | ||
+ | PS C:\inetpub\AspNetCoreWebApps> mkdir regsvr | ||
+ | |||
+ | Directory: C:\inetpub\AspNetCoreWebApps | ||
+ | |||
+ | Mode LastWriteTime Length Name | ||
+ | ---- ------------- ------ ---- | ||
+ | d----- 6/18/2020 11:33 PM regsvr | ||
+ | |||
+ | PS C:\inetpub\AspNetCoreWebApps> cd regsvr | ||
+ | |||
+ | Invoke-WebRequest -Uri "https://elasticbeanstalk-us-east-2-522802581903.s3.us-east-2.amazonaws.com/registryserver/registryserver-app-20061816.zip" -OutFile "registryserver-app-20061816.zip" | ||
+ | Expand-Archive -LiteralPath registryserver-app-20061816.zip -DestinationPath . | ||
+ | |||
+ | </pre> | ||
===Questions and Answers for Designers and Developers=== | ===Questions and Answers for Designers and Developers=== | ||
Line 161: | Line 270: | ||
* or, if it not there already | * or, if it not there already | ||
PS C:\WINDOWS\system32> New-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name ASPNETCORE_ENVIRONMENT -Value "Development" | PS C:\WINDOWS\system32> New-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name ASPNETCORE_ENVIRONMENT -Value "Development" | ||
+ | |||
ASPNETCORE_ENVIRONMENT : Development | ASPNETCORE_ENVIRONMENT : Development | ||
− | PSPath : | + | PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session |
− | Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session | ||
Manager\Environment | Manager\Environment | ||
PSParentPath : | PSParentPath : | ||
Line 170: | Line 279: | ||
PSProvider : Microsoft.PowerShell.Core\Registry | PSProvider : Microsoft.PowerShell.Core\Registry | ||
+ | Exporting a private key | ||
+ | <pre> | ||
+ | PS Cert:\LocalMachine\my> $pw = ConvertTo-SecureString -str "***" -fo -aspl | ||
+ | PS Cert:\LocalMachine\my> dir c1* | Export-PfxCertificate -FilePath C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryS | ||
+ | erver\private\localhost.pfx -Pass $pw | ||
+ | |||
+ | Directory: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\private | ||
+ | |||
+ | Mode LastWriteTime Length Name | ||
+ | ---- ------------- ------ ---- | ||
+ | -a---- 2020-06-09 6:22 PM 2661 localhost.pfx | ||
+ | </pre> | ||
+ | |||
+ | Load key to aws (This only applies if the HTTPS termination is to an AWS load balancer) | ||
+ | aws iam upload-server-certificate --server-certificate-name localhost --certificate-body .\localhost-public.pem --private-key .localhost-private.pem | ||
+ | |||
+ | Use the window's certutil tool to encode a file to Base64 (ie PEM). This command should add the appropriate certificate header: | ||
+ | certutil -encode {YOUR_PFX_FILE} {CONVERTED_FILE_NAME} | ||
Line 186: | Line 313: | ||
*The Microsoft web site has a description of the [https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnet.identity.corecompat Namespaces in ASP.NET Core] that can be used as an alternate identity schema. It was the precursor for the schema used here. | *The Microsoft web site has a description of the [https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnet.identity.corecompat Namespaces in ASP.NET Core] that can be used as an alternate identity schema. It was the precursor for the schema used here. | ||
+ | * [https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html AWS Working with Server Certificates] | ||
===Issues and Comments=== | ===Issues and Comments=== | ||
− | + | * Also see wiki page [[Publish Project to AWS]] | |
Latest revision as of 08:36, 12 October 2022
Contents
- 1 Full Title and Meme
- 2 Content
- 3 Details of Implementation
- 4 Working Notes
- 5 References and Coordination
Full Title and Meme
Best Practice and Example Trust Registry
Content
Goals of the Best Practices and Example
In furtherance of the objective of an ecosystem of trusted identities in cyberspace, it is incumbent on the various working of standards organization like the OpenID Foundation and the Kantara Initiative to produce guidance on the use of their work product. This example is designed to provide one way in which compliance can be earned.
The goals set out the needs and constraints on an example for use by any Trust Registry systems design.
- Support Federation to more that one external widely used or IDEF compliant Best Practice and Example Relying Party.
- Support two factor authentication.
- Support various stake-holders of compliant Identity systems, such as Health Care and Government.
Non-goals for this Example
This project is limited to the case of a Web Site or Native App that wants to prove compliance with a set of regulations.
Design Thinking
Given the goals above, design thinking is needed to produce a solution in the form of patterns which meets the user's desires and intent. For example in the need to capture the user's acceptance of the privacy policy and the terms of use, a design pattern could just let the user read and accept the site's stated policies. But what the user wants is control on how their private information is used. The solution below tries to address both the RP site goals and the user desires in a way that allows users to see their past expressed intent and change it as befits their current intent. This is in keeping with the Usable Best Practice A of the IDEF requirements.
Access to the Example
Currently a working implementation of the Trust Registry web site is available here https://trustregistry.us
Identifier used in Best Practices
Selection of the format of the Identifier
The operating assumption is that any identifier used for authentication must be unique and work effectively on the internet. On the internet unique identifiers are created as a scheme under the Uniform_Resource_Identifier (URI) as defined in RFC 3986. The only scheme that is widely used for identifiers is the mailto: scheme specified in RFC 822 and RFC 1122 where it is defined as "a@b.c" where "a" is usually considered to be a name and "b.c" to be the Identity Provider (IdP). While other identifiers have been created by IdPs, only the mailto: scheme is both URI compliant and well known to the community and so it is the recommended best practice for Kantara use. The specific technical reason for defining the identifier in such a limited structure is so that the RP can find the IdP configuration by looking at some well known URL (see RFC 5785) for that information. (n. b. The OpenID 1.0 code required a different syntax for identifiers that uses URL encoding of a.b.c described in the acct: scheme. There are a few existing Open ID providers that still use only the acct: scheme. If they have not fixed their code to permit the mailto: scheme for acquiring configuration information, they will not be able to provision IDs for this design.)
With the rise of personal communication devices, the internet may not be to the only source of user identifiers. Specifically one good practice is to use the user's cell phone number for authentication. The security and privacy of other authentication identifiers should be explained to the user before they are permitted to select one.
It is not required that any identifier is provisioned with an email (see RFC 7505) or other account that can receive notifications. However, if the relying party wants to use an account for notifications they should verify that the account provided belongs to a user that is willing to receive notifications. It is not sufficient simply to ask the user that is registering with the relying party since an attacker could be trying to send unwanted notifications to the unsuspecting owner of the account. Therefore it is incumbent on the relying party to verify the validity of the account by sending a verification to the account and awaiting a favorable response from someone that can access the account before adding the identifier to a list to receive notifications. This best practice applies to applications installed on mobile devices as well as to web browsers.
Compliance and Recovery of User Identifiers
To minimize the cognitive load on the user, this example asks for the user name in the form of an email address and then populates both the user name and the user email address fields of the database with that one string. If the user starts from a federated identity, like Google, that will be the user's email address at the federated IdP. If the user creates their own logon first then the Google email address will not be stored anywhere as the user identifier from Google is unique to the Google sign in identifier. While that provides some privacy protection, it is only because the user name appears in text form only for limited parts of the interchange, all of which should be protected by TLS. If user cognitive overload is not a primary concern the implementation could be changed to force the user to pick a user name as describe below in this same section.
The identifier used for authentication of a user is not well suited as the primary database key for the user since the specific IdP selected by the user for authentication is known to change over time. For this reason the identifier in the example database is a simple GUID which is statistically sure to be unique. Also the example allows for more than one authentication scheme to be enabled by a user. This choice carries some cognitive load for the user as the specific identifier selected by the user at registration must be known by the user at the time of later authentication. For that reason it is best practice for the RP to provide the user with other means to request their authentication (signin) identifier, which is yet another reason for the user to register an email address or phone number to receive the forgotten information.
If the RP registers itself with a federated IdP (like: this example, Microsoft or Google) then the user's email address never needs to be exposed to the RP in any situation, only the GUID assigned by the IdP which is put into the signin data table. If the user tries authentication with a dynamically registered IdP with OpenId Connect, then the user's email address must be requested by the RP for the purposes of locating the configuration information of the IdP. Note that the name part of the user email address is not required, but there is unlikely to be any user experience that would allow that distinction. Note that the OpenId Connect compliance certification process requires dynamic registration with a TCP port number, which is bad privacy practice and incompatible with the known naming schemes listed above. That requires special code to be inserted into the example for the sole purpose of OpenID compliance, and is never used in production.
For compliance tests of the RP system by a privacy auditor, the database dump will show that for preregistered federated IDs, the user email address is not stored in the database. It is likely that compliance tests will force the UX to be modified to encourage the user to enter a user name for display within the RP registration name space that is not related to any email or real world name and address. If the RP requires a real-world name and address for its own compliance criteria, then that must remain distinct from the user display name and the user email address. Any real-world identification information must be protected as befits the compliance criteria that the RP chooses to adopt.
Identifier from federated IdPs
Note that the identity stored in the user logins table is typically anonymized by the IdP so that it bears no relation to the user's URI at that IdP. So it is possible to use Google as for sign in to the RP web site without ever seeing or storing the email address that Google uses as a URI. Note that this is not guaranteed by Google. Since most IdPs of interest use OpenID Connect, the OAUTH 2.0 request to Google from the RP could ask for any of the profile information kept by Google. If the user declines to release the information to the RP, the authentication attempt with OpenID Connect will fail. From that persective OpenID connect is doing nothing within the protocol to protect User Private Information. It is up to the RP to ask for the minimum required information.
User Experience at the RPs
The user needs to be able to understand the nature of the Identity Model that is the basis for the User Private Information held by the RP. The sample below shows on the left side a typical federated ID site with a collection of well-known social sites plus a place for a username if that's what the user prefers. The right side of the images shows the next page after the user has selected a social site for signin. This images shows some good patterns as well as some bad (anti-) patterns. First the good. the user knows what attributes are being requested by the RP from the social site. It is also good that the page shows the user how to change the permissions for user attributes granted to it. The bad is that the user cannot change the user attributes that are selected on first signin. Also the terms and privacy statement are dense legalese which are written to protect the site owner. Terms that are hard for the user to understand will not be permissible in the EU once the GDPR comes into force in May 2018.
Personal Information evaluated for use in the Example
Note that the term Individual here means a human being. That should not be considered to prevent the RP from also supporting non human users.
- Categories of data editing enabled for users of data contained in the user data base (these categories are shown part of the data base schema, but some fields may change categories as the relationship between the user and RP changes over time):
- Required by the operation of the site and not editable,
- Required by the site owner but editable by the user,
- Optional data editable by the user,
- Links from external IdPs that are removable by the user,
- Data provided by 3rd parties together with a link to those 3rd parties for redress by the user.
- Data provided by 3rd parties can be marked as in dispute by the user if they cannot alter it.
- Personal data evaluated against the above categories is shown in the following model of the user. Where possible names used in the model match those used in the Open ID Connect standard claims. In those cases the lower case underline separate name was converted to a user friendly spelling and the background highlight with blue. Strictly speaking identity claims data is ONLY relevant in the AspNetUserLogins table, so this linkage is only for convenience as a taxonomy of the element names.
For more information see this page on User Private Information.
Model of the User in the Database
The goal of the data collected (as a User Object) about the individual and organizational users is to model the Users that are served by the web site with User Private Information intended for release by the users. Field names taken from other standards, like Open ID Connect, are highlighted in blue. This is a practice where the RP can determine the category tag used on each data field in advance based on the needs of the site. It may be necessary for the RP get user consent which requires that some fields are dynamically tagged based on user intent or user actions. In those cases a more complex design might be required. For example a deletion date may need to be associated with some fields.
Element Name | Contents | Cat | Explanation for category |
ID | identifier unique within the db | 1 | required for internal lookups |
Status | Boolean | 1 | yes = active, no = inactive (entries are never deleted) |
Type | numeric | 1 | (1)individual, (2)organization (can be a parent), (3) pseudonym (avoid any linkage) |
Parent | link (exactly one) | 2 | link to an organization in this db, the default parent is the federation root entry |
Member | code | 1 | 0=none, 1= member in good standing, 2=candidate for membership, 3=suspended or resigned |
Role | link (zero or more) | 1 | none, registered member, member of the parent member, voting member of the parent, site admin |
Email Type | 3 | 0=untyped, 1=prohibited, 2=allowed, 3=digest only | |
ui locales | URI | 3 | User's preferred languages, represented as a space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. For instance, the value "fr-CA fr en" represents a preference for French as spoken in Canada, then French (without a region designation), followed by English (without a region designation). |
ZoneInfo | URI | 3 | time zone for the named individual, it has less relevance for orgs |
URI | 2 | this example assumes that contact with the user is required, also used for recovery. While it is possible for later reuse of the email name to cause a collision, this needs to be considered as unique at the time it was verified. | |
Email Verified | Boolean | 1 | to avoid spam against some email that has been entered without the owner's knowledge |
Password Hash | hash | 3 | to allow user access local to the web site - only one authN method is required |
Federated Logins | link (zero or more) | 4 | The example shows how to create these for Google and Facebook |
Security Stamp | byte string | 1 | |
Phone Number | string | 3 | not required in this example, also used for recovery with SMS. As with email this ID can be compromised or reused at a later time, but would be unique when verified. |
Phone Number Verified | Boolean | 1 | May be required if the telephone number is entered in order to avoid spamming. |
Two Factor Enabled | Boolean | 5 | User choice at first, this should be moved to the authN table |
Lockout end date | Date | 1 | set by the system when lockout occurs - since the user is locked out, this cannot be changed |
Lockout enabled | Boolean | 1 | Not required on this site - possibly the value could be given to the user |
Access Failed | count | 1 | site accounting |
Legal name | alphanumeric | 2 | Since the key is the ID, this can be changed, but only when legal documents are change as well - It is never displayed except to site admins |
Display name | alphanumeric | 3 | So that members will know how to refer to each other aka user or username |
Stipulation | link to document (zero or more) | 2 | User accepted stipulation on privacy, ToU, IPR or other policy together with any user response |
Site documents and user expressed intent
See the page at Best Practice and Example Relying Party for a way to track User Stipulations..
Details of Implementation
- Code for the Health Care Native App Example has been upgraded (2020-05-08) to ASP.NET Core 3.1
- The SDK is NETSTANDARD 2.0 which works on Windows UWP, Google Android and Apple iOS.
- Using just MVC core rather than MVC.
- The Crypto is RSA class using the RSACryptoServiceProvider. There is an issue setting the key size as described here for keys other than the default 1024.
- Implementation uses .net core 2.2 with SQL server supported on AWS with this tooling
- In order to reduce the overhead of restarting services that are used for http request, a service is created. For ASP.NET core the advice is to establish a singleton hosted process. For guidance see AddTransient, AddScoped and AddSingleton Services Differences.
Protection of Keys
The security of the registry depends on the protection of the signing hey, which should be treated in a manner like that of a Certificate Authority.
- requirements of the CA|B forum while quantum key protection is not specifically mentioned, it should be inferred. Note the the life of the master key is typically on the order of 25 years.
6.2. PRIVATE KEY PROTECTION AND CRYPTOGRAPHIC MODULE ENGINEERING CONTROLS
The CA SHALL implement physical and logical safeguards to prevent unauthorized certificate issuance. Protection of the CA Private Key outside the validated system or device specified above MUST consist of physical security, encryption, or a combination of both, implemented in a manner that prevents disclosure of the CA Private Key. The CA SHALL encrypt its Private Key with an algorithm and key-length that, according to the state of the art, are capable of withstanding cryptanalytic attacks for the residual life of the encrypted key or key part.
Best Practice would ensure that not access was granted to any application running on the front end server accessible from external web addresses. The processes that can access the signing or decryption keys should only be accessed on internal networks preferably as micro-services. This implies that the ssl certs and keys used on the front web connections are not adequate for signing of protected documents. Decryption services may still be accessed from front end services unless the keys are shared with signing services, which is probably not the best design.
Best Practice for micro-services in internal, hardware protection of keys and self-signed certs that are included in the cert:\localmachine\root storage locations.
- CNG Key Storage and Retrieval in Windows.
Discovery Endpoint
Callable at https://trustregistry.us/
Credential Service Endpoint
Callable at https://trustregistry.us/csp
Working Notes
Next steps
Set up goals and start to build examples and best practices for all of the roles in an ID ecosystem.
- separate front end in iis from registry server in Kestrel for api processing
- put simpleservice for gPRC in same deploy package as registry server
- if the error "The library 'hostpolicy.dll' required to execute the application was not found" comes the following fix worked
PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1> dir C:\Users\rp_to_000\Documents\TopCat \Repos\TrustRegistry3\SimpleService\bin\Debug\netcoreapp3.1\sim*config*.json Directory: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\SimpleService\bin\Debug\netcoreapp3.1 Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2020-06-07 4:53 PM 284 SimpleService.runtimeconfig.dev.json -a---- 2020-06-07 4:53 PM 288 SimpleService.runtimeconfig.json PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1> copy C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\SimpleService\bin\Debug\netcoreapp3.1\sim*config*.json . PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1> .\SimpleService.exe Hosting environment: Development Content root path: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\bin\Debug\netcoreapp3.1\ Now listening on: https://localhost:5033 Application started. Press Ctrl+C to shut down.
Trust Registry Build and Deploy
This is the front end process designed to run under IIS.
- Windows Registry settings to enable a windows event log for this application
- Note that these are in the local machine branch and so must be run with admin creds.
C:\certs> reg import .\trustregistry.reg or C:\certs> regedit /s .\trustregistry.reg
Where the following content is in that file:
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\TrustRegistry] "EventMessageFile"=hex(2):43,00,3a,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,\ 00,73,00,5c,00,4d,00,69,00,63,00,72,00,6f,00,73,00,6f,00,66,00,74,00,2e,00,\ 4e,00,45,00,54,00,5c,00,46,00,72,00,61,00,6d,00,65,00,77,00,6f,00,72,00,6b,\ 00,36,00,34,00,5c,00,76,00,34,00,2e,00,30,00,2e,00,33,00,30,00,33,00,31,00,\ 39,00,5c,00,45,00,76,00,65,00,6e,00,74,00,4c,00,6f,00,67,00,4d,00,65,00,73,\ 00,73,00,61,00,67,00,65,00,73,00,2e,00,64,00,6c,00,6c,00,00,00
Registry Server Build and Deploy
This is the API process designed to run under Kestrel so that it can support HTTP/2 access to the Simple Service.
It is designed for dotnetcore 3.1 running as a windows service. This means that it will be started from C:/Windows/System32, which will set Content Root incorrectly if the createdefaultbuilder method is used in prograam.cs.
In this example the date should be the current date.
cd C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer dotnet publish .\private\CleanUp.ps1 .\private\rs-deploy.ps1 PS C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\private> dir *200618* Directory: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\private Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2020-06-18 4:13 PM 4890460 registryserver-app-20061816.zip -a---- 2020-06-18 4:13 PM 4869241 registryserver-deploy-20061816.zip go to Amazon S3/elasticbeanstalk-us-east-2-522802581903/registryserver upload registryserver-app-20061816.zip make sure that the upload completed successfully - retry if not make file public copy the url go to AWS system manager> session manager click start session select us-east-2 click start session S C:\Windows\system32> cd C:\inetpub\AspNetCoreWebApps\ PS C:\inetpub\AspNetCoreWebApps> dir Directory: C:\inetpub\AspNetCoreWebApps Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 6/18/2020 4:23 AM app d----- 6/16/2020 9:21 PM regsvr d----- 6/9/2020 9:08 PM regsvr1 d----- 6/15/2020 8:39 PM regsvr2 PS C:\inetpub\AspNetCoreWebApps> ren .\regsvr\ .\regsvr-200616 PS C:\inetpub\AspNetCoreWebApps> mkdir regsvr Directory: C:\inetpub\AspNetCoreWebApps Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 6/18/2020 11:33 PM regsvr PS C:\inetpub\AspNetCoreWebApps> cd regsvr Invoke-WebRequest -Uri "https://elasticbeanstalk-us-east-2-522802581903.s3.us-east-2.amazonaws.com/registryserver/registryserver-app-20061816.zip" -OutFile "registryserver-app-20061816.zip" Expand-Archive -LiteralPath registryserver-app-20061816.zip -DestinationPath .
Questions and Answers for Designers and Developers
Will need to build for best practices:
- Consent Receipt (CR)
- Privacy policy (PP)
- Terms of use (ToU)
- Are there specific ToU and PP provisions that demonstrate how the Trust Registry
Set Development environment for development computer:
- $env:ASPNETCORE_ENVIRONMENT = "Development"
- Set-ItemProperty -ASPNETCORE_ENVIRONMENT 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name ASPNETCORE_ENVIRONMENT -Value "Development"
- or, if it not there already
PS C:\WINDOWS\system32> New-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name ASPNETCORE_ENVIRONMENT -Value "Development"
ASPNETCORE_ENVIRONMENT : Development PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager PSChildName : Environment PSProvider : Microsoft.PowerShell.Core\Registry
Exporting a private key
PS Cert:\LocalMachine\my> $pw = ConvertTo-SecureString -str "***" -fo -aspl PS Cert:\LocalMachine\my> dir c1* | Export-PfxCertificate -FilePath C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryS erver\private\localhost.pfx -Pass $pw Directory: C:\Users\rp_to_000\Documents\TopCat\Repos\TrustRegistry3\RegistryServer\private Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2020-06-09 6:22 PM 2661 localhost.pfx
Load key to aws (This only applies if the HTTPS termination is to an AWS load balancer)
aws iam upload-server-certificate --server-certificate-name localhost --certificate-body .\localhost-public.pem --private-key .localhost-private.pem
Use the window's certutil tool to encode a file to Base64 (ie PEM). This command should add the appropriate certificate header:
certutil -encode {YOUR_PFX_FILE} {CONVERTED_FILE_NAME}
UX Questions Specific to the RP example code
- Demo verification of email (or cell phone) address - will be needed in the future
- What are the canonical terms for identification?
- logon logout register resign
- login logoff create remove
- signin signout signup signoff
- User roles - how to model - note that one user can have multiple roles
Other issues to look at:
- Some method for creating a strong web site identity, e.g. Federation or EV Certs
References and Coordination
- The Microsoft web site has a description of the Namespaces in ASP.NET Core that can be used as an alternate identity schema. It was the precursor for the schema used here.
- AWS Working with Server Certificates
Issues and Comments
- Also see wiki page Publish Project to AWS