{"id":20718633,"url":"https://github.com/os2web/os2web_key","last_synced_at":"2026-02-28T15:31:59.313Z","repository":{"id":236252586,"uuid":"792232482","full_name":"OS2web/os2web_key","owner":"OS2web","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-13T08:12:30.000Z","size":465,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-19T14:48:53.583Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OS2web.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-26T08:42:59.000Z","updated_at":"2025-05-13T08:09:16.000Z","dependencies_parsed_at":"2025-10-19T02:30:23.572Z","dependency_job_id":"2f395d5a-f1bd-4e74-a5eb-88baae5554ce","html_url":"https://github.com/OS2web/os2web_key","commit_stats":null,"previous_names":["rimi-itk/os2web_key"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/OS2web/os2web_key","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OS2web%2Fos2web_key","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OS2web%2Fos2web_key/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OS2web%2Fos2web_key/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OS2web%2Fos2web_key/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OS2web","download_url":"https://codeload.github.com/OS2web/os2web_key/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OS2web%2Fos2web_key/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29940284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T13:49:17.081Z","status":"ssl_error","status_checked_at":"2026-02-28T13:48:50.396Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T03:14:19.091Z","updated_at":"2026-02-28T15:31:59.284Z","avatar_url":"https://github.com/OS2web.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OS2Web key\n\nKey types and providers for OS2Web built on the [Key module](https://www.drupal.org/project/key).\n\nThe OS2Web key module provides two _key types_, [Certificate](#certificate) and [OpenID Connect\n(OIDC)](#openid-connect-oidc). It also comes with two _key providers_,\n[Azure Key Vault](#azure-key-vault) and [HashiCorp Vault](#hashicorp-vault).\n\nSee [the Key Developer Guide](https://www.drupal.org/docs/contributed-modules/key/developer-guide) for details in how to\nuse keys in Drupal.\n\n## Installation\n\n``` shell\ncomposer require os2web/os2web_key\ndrush pm:install os2web_key\n```\n\nKeys are managed on `/admin/config/system/keys`.\n\n## Key types\n\n### Certificate\n\nThis key type handles [PKCS 12](https://en.wikipedia.org/wiki/PKCS_12) or [Privacy-Enhanced Mail\n(PEM)](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) certificate with an optional password (passphrase).\n\nManaging the key:\n\n![\"Certificate\" key type form](docs/assets/key-type-certificate.png)\n\nUse in a form:\n\n``` php\n$form['key'] =\u003e [\n '#type' =\u003e 'key_select',\n '#key_filters' =\u003e [\n   'type' =\u003e 'os2web_key_certificate',\n ],\n];\n```\n\nThe [`KeyHelper`](https://github.com/OS2web/os2web_key/blob/main/src/KeyHelper.php) can be used to get\nthe actual certificates (parts):\n\n``` php\n\u003c?php\n\nuse Drupal\\os2web_key\\KeyHelper;\nuse Drupal\\key\\KeyRepositoryInterface;\n\n// Use dependency injection for this.\n/** @var KeyRepositoryInterface $repository */\n$repository = \\Drupal::service('key.repository');\n/** @var KeyHelper $helper */\n$helper = \\Drupal::service(KeyHelper::class);\n\n// Use `drush key:list` to list your keys.\n$key = $repository-\u003egetKey('my_key');\n[\n  // Passwordless certificate.\n  CertificateKeyType::CERT =\u003e $certificate,\n  CertificateKeyType::PKEY =\u003e $privateKey,\n] = $helper-\u003egetCertificates($key);\n\n```\n\n**Note**: The parsed certificate has no password.\n\n### OpenID Connect (OIDC)\n\nManaging the key:\n\n![\"OpenID Connect (OIDC)\" key type form](docs/assets/key-type-oidc.png)\n\nExample use in a form:\n\n``` php\n$form['key'] =\u003e [\n '#type' =\u003e 'key_select',\n '#key_filters' =\u003e [\n   'type' =\u003e 'os2web_key_oidc,\n ],\n];\n```\n\nGet the OIDC config:\n\n``` php\n\u003c?php\n\nuse Drupal\\key\\KeyRepositoryInterface;\nuse Drupal\\os2web_key\\Plugin\\KeyType\\OidcKeyType;\n\n// Use dependency injection for this.\n/** @var KeyRepositoryInterface $repository */\n$repository = \\Drupal::service('key.repository');\n\n$key = $repository-\u003egetKey('openid_connect_ad');\n[\n  OidcKeyType::DISCOVERY_URL =\u003e $discoveryUrl,\n  OidcKeyType::CLIENT_ID =\u003e $clientId,\n  OidcKeyType::CLIENT_SECRET =\u003e $clientSecret,\n] = $helper-\u003egetOidcValues($key);\n```\n\n## Providers\n\nThe module comes with two key providers.\n\n### Azure Key Vault\n\nUsed for fetching certificate from Azure Key vault.\n\n### HashiCorp Vault\n\nUsed to fetch any sort of secret string from HashiCorp vault. Note that\nthis can only provide string values, i.e. no binary files.\n\nTo use this provider you must configure the following in `settings.local.php`:\n\n``` php\n$settings['os2web_vault_role_id'] = '{ROLE_ID}';\n$settings['os2web_vault_secret_id'] = '{SECRET_ID}';\n$settings['os2web_vault_url'] = '{VAULT_URL}';\n```\n\n## Coding standards\n\nOur coding are checked by GitHub Actions (cf. [.github/workflows/pr.yml](.github/workflows/pr.yml)). Use the commands\nbelow to run the checks locally.\n\n### PHP\n\n```shell\ndocker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.3-fpm composer install\n# Fix (some) coding standards issues\ndocker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.3-fpm composer coding-standards-apply\n# Check that code adheres to the coding standards\ndocker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.3-fpm composer coding-standards-check\n```\n\n### Markdown\n\n```shell\ndocker run --rm --volume $PWD:/md peterdavehello/markdownlint markdownlint --ignore vendor --ignore LICENSE.md '**/*.md' --fix\ndocker run --rm --volume $PWD:/md peterdavehello/markdownlint markdownlint --ignore vendor --ignore LICENSE.md '**/*.md'\n```\n\n## Code analysis\n\nWe use [PHPStan](https://phpstan.org/) for static code analysis.\n\nRunning static code analysis on a standalone Drupal module is a bit tricky, so we use a helper script to run the\nanalysis:\n\n```shell\ndocker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.3-fpm ./scripts/code-analysis\n```\n\n## Unit tests\n\nWe use [PHPUnit](https://phpunit.de/documentation.html) for unit testing.\n\nTesting mostly centers around the conversion and parsing of certificates. For this purpose a bunch of test\ncertificates has been generated. See [Test certificates](#test-certificates) for how this is done.\n\nRunning PHPUnit tests in a standalone Drupal module is a bit tricky, so we use a helper script to run the\nanalysis:\n\n```shell\ndocker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.3-fpm ./scripts/unit-tests\n```\n\n### Test certificates\n\nCertificates have been generated in the follow way\n\n```shell\n# p12 with password\nopenssl req -x509 -newkey rsa:4096 -days 365 -subj \"/CN=example.com\" -passout pass:test -keyout test.key -out test.crt\nopenssl pkcs12 -export -out test_with_passphrase.p12 -passin pass:test -passout pass:test -inkey test.key -in test.crt\nopenssl pkcs12 -in test_with_passphrase.p12 -passin pass:test -noenc\n\n# p12 without password\nopenssl req -x509 -newkey rsa:4096 -days 365 -subj \"/CN=example.com\" -passout pass:''   -keyout test_without_passphrase.key -out test_without_passphrase.crt\nopenssl pkcs12 -export -out test_without_passphrase.p12 -passin pass:'' -passout pass:'' -inkey test_without_passphrase.key -in test_without_passphrase.crt\nopenssl pkcs12 -in test_without_passphrase.p12 -passin pass:'' -noenc\n\n# PEM with password\nopenssl req -x509 -newkey rsa:4096 -days 365 -subj \"/CN=example.com\" -passout pass:test -keyout test.key -out test.crt\ncat test.crt test.key \u003e test_with_passphrase.pem\nopenssl x509 -in test_with_passphrase.pem\n\n# PEM without password\nopenssl req -x509 -newkey rsa:4096 -days 365 -subj \"/CN=example.com\" -passout pass:''   -keyout test_without_passphrase.key -out test_without_passphrase.crt -noenc\ncat test_without_passphrase.crt test_without_passphrase.key \u003e test_without_passphrase.pem\nopenssl x509 -in test_without_passphrase.pem\n```\n\nExtraction of certificate and private key parts in the following way\n\n```shell\n# P12 with passphrase\nopenssl pkcs12 -in test_with_passphrase.p12 -passin pass:test -clcerts -nokeys | sed -ne '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \u003e p12_with_passphrase_cert.txt\nopenssl pkcs12 -in test_with_passphrase.p12 -passin pass:test -nocerts -nodes | sed -ne '/-----BEGIN PRIVATE KEY-----/,/-----END PRIVATE KEY-----/p' \u003e p12_with_passphrase_pkey.txt\n\n# P12 without passphrase\nopenssl pkcs12 -in test_without_passphrase.p12 -passin pass: -clcerts -nokeys | sed -ne '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \u003e p12_without_passphrase_cert.txt\nopenssl pkcs12 -in test_without_passphrase.p12 -passin pass: -nocerts -nodes | sed -ne '/-----BEGIN PRIVATE KEY-----/,/-----END PRIVATE KEY-----/p' \u003e p12_without_passphrase_pkey.txt\n\n# PEM with passphrase\nopenssl x509 -in test_with_passphrase.pem -passin pass:test -out pem_with_passphrase_cert.txt\nopenssl pkey -in test_with_passphrase.pem -passin pass:test -out pem_with_passphrase_pkey.txt\n\n# PEM without passphrase\nopenssl x509 -in test_without_passphrase.pem -passin pass: -out pem_without_passphrase_cert.txt\nopenssl pkey -in test_without_passphrase.pem -passin pass: -out pem_without_passphrase_pkey.txt\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fos2web%2Fos2web_key","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fos2web%2Fos2web_key","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fos2web%2Fos2web_key/lists"}