GitHub App Integration
-GitHub App Integration is alternative of GitHub OAuth2. To create GitHub go to -Settings / Developer settings / GitHub Apps and click New GitHub App.
-Use the next "Callback URL / Redirect URL".
-Redirect Urls:
-https://example.com/oauth2/{alias}/install
-https://example.com/oauth2/{alias}/check
+GitHub App Integration is alternative of GitHub OAuth2.
+To create GitHub go to: Settings / Developer settings / GitHub Apps and click New GitHub App
.
+
+- Enter a GitHub App name: Private Packeton.
+- Enter a homepage url: https://packeton.example.com for example.
+- Click
Add Callback URL
and use the next "Callback URL / Redirect URL".
+
+https://packeton.example.com/oauth2/{alias}/install
+https://packeton.example.com/oauth2/{alias}/check
-The webhooks URL maybe any. We don't use it and setup webhooks per repository or choice organization.
-Select Permissions:
-- Webhooks read-write (Repository permissions)
-- Metadata (Repository permissions)
-- Pull requests read-write (Repository permissions)
-- Webhooks read-write (Organization permissions)
-- Members read (Organization permissions) - optional
+- Uncheck webhook active checkbox
+
+Select Repository permissions:
+
+- Content: read-only
+- Webhooks: read-write
+- Metadata: read-only (already selected)
+- Pull requests read-write
+
+Select Organization permissions:
+
+- Webhooks: read-write
+- Members: read (optional)
After creating App go to App view page and find app_id
and generate a "Private Key"
@@ -178,12 +187,15 @@
-When you must install GitHub App in you Github Account. Go to public App page, like https://github.com/apps/{name}
-and click configure. Select you organization or own account.
When you must install GitHub App in your GitHub Account.
+Go to public App page, like https://github.com/apps/{name}
and click configure.
+Select your organization or own account.
After install you will see installation_id
on URL address. For example https://github.com/settings/installations/38069000
Now go to Packeton integration page and click Install Integration. When click to Connect under you githubapp configuration.
-To finish setup Go to Packeton integration view page / Settings and provider installation_id
in the form
Now go to Packeton integration
page and click Install Integration
.
+When click to Connect
under you github
configuration.
To finish setup Go to Packeton integration
view page / Settings and provider installation_id
in the form
Table o
Bitbucket Setup
Base configuration reference
-To enable OAuth2 integrations you need to add following configuration
+To enable OAuth2 integrations, you need to add the following configuration
packeton:
integrations:
github: # Alias name
@@ -2664,8 +2664,8 @@ GitLab
GitLab Groups Webhooks notices
A group webhooks needed for synchronization a new package.
They are triggered by events that occur across all projects in the group.
-This feature enabled only for Premium / EE / Gold paid plan, but it can be replaced with GitLab Packagist Integration
-You must manually setup this integration.
+This feature is enabled only for Premium / EE / Gold paid plan, but it can be replaced with GitLab Packagist Integration
+You must manually set up this integration.
Where token you can find on the packeton integration view page. The token must have whk
prefix
to find related integration access token.
@@ -2717,7 +2717,7 @@
-
Use obtained clinent_id
, client_secret
to create configuration in yaml. For docker installation you may use config.yaml
file in docker volume.
+Use obtained client_id
, client_secret
to create configuration in yaml. For docker installation you may use config.yaml
file in docker volume.
packeton:
integrations:
github: # any alias name
@@ -2727,25 +2727,34 @@
GitHub App Integration
-
GitHub App Integration is alternative of GitHub OAuth2. To create GitHub go to
-Settings / Developer settings / GitHub Apps and click New GitHub App.
-Use the next "Callback URL / Redirect URL".
-Redirect Urls:
-https://example.com/oauth2/{alias}/install
-https://example.com/oauth2/{alias}/check
+GitHub App Integration is alternative of GitHub OAuth2.
+To create GitHub go to: Settings / Developer settings / GitHub Apps and click New GitHub App
.
+
+- Enter a GitHub App name: Private Packeton.
+- Enter a homepage url: https://packeton.example.com for example.
+- Click
Add Callback URL
and use the next "Callback URL / Redirect URL".
+
+https://packeton.example.com/oauth2/{alias}/install
+https://packeton.example.com/oauth2/{alias}/check
-The webhooks URL maybe any. We don't use it and setup webhooks per repository or choice organization.
-Select Permissions:
-- Webhooks read-write (Repository permissions)
-- Metadata (Repository permissions)
-- Pull requests read-write (Repository permissions)
-- Webhooks read-write (Organization permissions)
-- Members read (Organization permissions) - optional
+- Uncheck webhook active checkbox
+
+Select Repository permissions:
+
+- Content: read-only
+- Webhooks: read-write
+- Metadata: read-only (already selected)
+- Pull requests read-write
+
+Select Organization permissions:
+
+- Webhooks: read-write
+- Members: read (optional)
After creating App go to App view page and find app_id
and generate a "Private Key"
@@ -2761,12 +2770,15 @@
After install you will see installation_id
on URL address. For example https://github.com/settings/installations/38069000
-Now go to Packeton integration page and click Install Integration. When click to Connect under you githubapp configuration.
-To finish setup Go to Packeton integration view page / Settings and provider installation_id
in the form
+Now go to Packeton integration
page and click Install Integration
.
+When click to Connect
under you github
configuration.
+
+To finish setup Go to Packeton integration
view page / Settings and provider installation_id
in the form
GitLab Integration Setup
Go to you GitLab account preferences (https://gitlab.example.com/-/profile/preferences
) and select "Applications"
diff --git a/searchindex.js b/searchindex.js
index eabe3402..0907e225 100644
--- a/searchindex.js
+++ b/searchindex.js
@@ -1 +1 @@
-Object.assign(window.search, {"doc_urls":["index.html#introduction","index.html#main-features","index.html#compare-private-packagist-with-packeton","installation.html#install-and-run","installation.html#installation","installation.html#requirements","installation.html#configuration","installation.html#ssh-key-access-and-composer-oauth-token","installation-docker.html#install-and-run-in-docker","installation-docker.html#quick-start","installation-docker.html#docker-environment","installation-docker.html#user-docker-compose","installation-docker.html#build-and-run-docker-container-with-docker-compose","reverse-proxy.html#using-a-reverse-proxy","reverse-proxy.html#reverse-proxy-configuration-examples","usage/index.html#administration","usage/index.html#table-of-content","usage/index.html#application-roles","usage/api.html#api-documentation","webhook.html#generic-packeton-webhooks","webhook.html#introduction","webhook.html#examples","webhook.html#twig-variables","webhook.html#telegram-notification","webhook.html#slack-notification","webhook.html#use-url-placeholder","webhook.html#interrupt-request","webhook.html#nesting-webhook","webhook.html#jira-create-a-new-release-and-set-fix-version","webhook.html#http-request-from-code","webhook.html#external-request","webhook.html#gitlab-auto-webhook","webhook.html#new-twig-functions","webhook.html#generic-packeton-webhooks","webhook.html#introduction","webhook.html#examples","webhook.html#twig-variables","webhook.html#telegram-notification","webhook.html#slack-notification","webhook.html#use-url-placeholder","webhook.html#interrupt-request","webhook.html#nesting-webhook","webhook.html#jira-create-a-new-release-and-set-fix-version","webhook.html#http-request-from-code","webhook.html#external-request","webhook.html#gitlab-auto-webhook","webhook.html#new-twig-functions","webhook.html#generic-packeton-webhooks","webhook.html#introduction","webhook.html#examples","webhook.html#twig-variables","webhook.html#telegram-notification","webhook.html#slack-notification","webhook.html#use-url-placeholder","webhook.html#interrupt-request","webhook.html#nesting-webhook","webhook.html#jira-create-a-new-release-and-set-fix-version","webhook.html#http-request-from-code","webhook.html#external-request","webhook.html#gitlab-auto-webhook","webhook.html#new-twig-functions","webhook/webhook-secrets.html#manage-secrets","webhook/webhook-secrets.html#encrypt-secrets","webhook/webhook-secrets.html#usage-secrets","webhook/wh-security.html#webhook-security","webhook/wh-test.html#test-webhook-twig-payload","usage/update-packages.html#how-to-auto-update-packages","usage/update-packages.html#into","usage/update-packages.html#bitbucket-webhooks","usage/update-packages.html#gitlab-service","usage/update-packages.html#gitlab-group-hooks","usage/update-packages.html#github-webhooks","usage/update-packages.html#gitea-webhooks","usage/update-packages.html#manual-hook-setup","usage/customers.html#customer-users","usage/customers.html#create-customer-user","usage/credential.html#ssh-credential-and-composer-auth","usage/credential.html#using-ui-credential-manager","usage/mirroring.html#mirroring-and-composer-proxies","usage/mirroring.html#main-features","usage/mirroring.html#configuration","usage/mirroring.html#metadata-proxy-specification","usage/mirroring.html#default-sync-intervals","usage/mirroring.html#commands-for-debug","usage/mirroring.html#manual-approval-of-dependencies","usage/mirroring.html#mirror-public-access","usage/mirroring.html#mirroring-and-composer-proxies","usage/mirroring.html#main-features","usage/mirroring.html#configuration","usage/mirroring.html#metadata-proxy-specification","usage/mirroring.html#default-sync-intervals","usage/mirroring.html#commands-for-debug","usage/mirroring.html#manual-approval-of-dependencies","usage/mirroring.html#mirror-public-access","usage/mirroring.html#mirroring-and-composer-proxies","usage/mirroring.html#main-features","usage/mirroring.html#configuration","usage/mirroring.html#metadata-proxy-specification","usage/mirroring.html#default-sync-intervals","usage/mirroring.html#commands-for-debug","usage/mirroring.html#manual-approval-of-dependencies","usage/mirroring.html#mirror-public-access","authentication.html#user-authentication","authentication.html#web-user-authentication","authentication.html#composer-api-authentication","authentication-jwt.html#jwt-api-authentication","authentication-jwt.html#generate-the-publicprivate-keys","authentication-jwt.html#jwt-token-ttl","authentication-jwt.html#digital-signatures-algos","authentication-jwt.html#generating-keys-using-openssl","authentication-jwt.html#obtain-the-token","authentication-jwt.html#use-the-token","authentication-ldap.html#authenticating-against-an-ldap-server","authentication-ldap.html#user-providers-priority","authentication-ldap.html#load-different-roles-from-ldap","authentication-ldap.html#api-authentication-with-ldap-users","authentication-ldap.html#enable-ldap-for-docker-runtime","usage/storage.html#s3-storage-provider","usage/custom-page.html#custom-landing-page","usage/custom-page.html#example-2","usage/security-monitoring.html#security-monitoring","usage/security-monitoring.html#configure-webhook-notifications","usage/migrate.html#migrate-from-packagistcom--satis","oauth2.html#oauth2-and-sync-integrations","oauth2.html#table-of-content","oauth2.html#base-configuration-reference","oauth2.html#docker-env","oauth2.html#supported-3-d-provider","oauth2.html#github","oauth2.html#gitlab","oauth2.html#gitea","oauth2.html#bitbucket","pull-request-review.html#pull-request-composer-lock-review","pull-request-review.html#configure-pull-request-review","oauth2/github-oauth.html#github-oauth2-setup","oauth2/githubapp.html#github-app-integration","oauth2/gitlab-integration.html#gitlab-integration-setup","oauth2/gitea.html#gitea-integration-setup","oauth2/bitbucket.html#bitbucket-integration-setup","oauth2/login-expression.html#limit-loginregister-with-using-expression-lang","oauth2/login-expression.html#custom-twig-function-for-expression-lang","oauth2/login-expression.html#debug-expressions","dev/CONTRIBUTING.html#contributing","dev/CONTRIBUTING.html#1-development-environment","dev/CONTRIBUTING.html#2-get-the-source","dev/CONTRIBUTING.html#3-install-the-dependencies","dev/CONTRIBUTING.html#4-configure-your-env-vars","dev/CONTRIBUTING.html#5-setup-database","dev/CONTRIBUTING.html#6-run-local-webserver","dev/CONTRIBUTING.html#enjoy","dev/configuration.html#configuration-reference"],"index":{"documentStore":{"docInfo":{"0":{"body":8,"breadcrumbs":2,"title":1},"1":{"body":71,"breadcrumbs":3,"title":2},"10":{"body":159,"breadcrumbs":4,"title":2},"100":{"body":67,"breadcrumbs":8,"title":3},"101":{"body":11,"breadcrumbs":8,"title":3},"102":{"body":12,"breadcrumbs":4,"title":2},"103":{"body":19,"breadcrumbs":5,"title":3},"104":{"body":89,"breadcrumbs":5,"title":3},"105":{"body":84,"breadcrumbs":7,"title":3},"106":{"body":24,"breadcrumbs":7,"title":3},"107":{"body":23,"breadcrumbs":7,"title":3},"108":{"body":35,"breadcrumbs":7,"title":3},"109":{"body":44,"breadcrumbs":8,"title":4},"11":{"body":219,"breadcrumbs":5,"title":3},"110":{"body":19,"breadcrumbs":6,"title":2},"111":{"body":42,"breadcrumbs":6,"title":2},"112":{"body":118,"breadcrumbs":8,"title":4},"113":{"body":45,"breadcrumbs":7,"title":3},"114":{"body":61,"breadcrumbs":8,"title":4},"115":{"body":22,"breadcrumbs":8,"title":4},"116":{"body":9,"breadcrumbs":8,"title":4},"117":{"body":135,"breadcrumbs":6,"title":3},"118":{"body":85,"breadcrumbs":6,"title":3},"119":{"body":10,"breadcrumbs":5,"title":2},"12":{"body":34,"breadcrumbs":8,"title":6},"120":{"body":38,"breadcrumbs":4,"title":2},"121":{"body":100,"breadcrumbs":5,"title":3},"122":{"body":151,"breadcrumbs":5,"title":3},"123":{"body":0,"breadcrumbs":5,"title":3},"124":{"body":16,"breadcrumbs":4,"title":2},"125":{"body":212,"breadcrumbs":5,"title":3},"126":{"body":46,"breadcrumbs":4,"title":2},"127":{"body":0,"breadcrumbs":6,"title":4},"128":{"body":9,"breadcrumbs":3,"title":1},"129":{"body":53,"breadcrumbs":3,"title":1},"13":{"body":9,"breadcrumbs":6,"title":3},"130":{"body":10,"breadcrumbs":3,"title":1},"131":{"body":11,"breadcrumbs":3,"title":1},"132":{"body":30,"breadcrumbs":10,"title":5},"133":{"body":58,"breadcrumbs":9,"title":4},"134":{"body":79,"breadcrumbs":7,"title":3},"135":{"body":150,"breadcrumbs":7,"title":3},"136":{"body":89,"breadcrumbs":7,"title":3},"137":{"body":73,"breadcrumbs":7,"title":3},"138":{"body":60,"breadcrumbs":7,"title":3},"139":{"body":102,"breadcrumbs":9,"title":5},"14":{"body":211,"breadcrumbs":7,"title":4},"140":{"body":37,"breadcrumbs":9,"title":5},"141":{"body":55,"breadcrumbs":6,"title":2},"142":{"body":5,"breadcrumbs":2,"title":1},"143":{"body":36,"breadcrumbs":4,"title":3},"144":{"body":16,"breadcrumbs":3,"title":2},"145":{"body":7,"breadcrumbs":4,"title":3},"146":{"body":11,"breadcrumbs":5,"title":4},"147":{"body":5,"breadcrumbs":4,"title":3},"148":{"body":5,"breadcrumbs":5,"title":4},"149":{"body":0,"breadcrumbs":2,"title":1},"15":{"body":6,"breadcrumbs":2,"title":1},"150":{"body":300,"breadcrumbs":4,"title":2},"16":{"body":20,"breadcrumbs":3,"title":2},"17":{"body":60,"breadcrumbs":3,"title":2},"18":{"body":229,"breadcrumbs":5,"title":2},"19":{"body":0,"breadcrumbs":6,"title":3},"2":{"body":194,"breadcrumbs":5,"title":4},"20":{"body":97,"breadcrumbs":4,"title":1},"21":{"body":28,"breadcrumbs":4,"title":1},"22":{"body":28,"breadcrumbs":5,"title":2},"23":{"body":38,"breadcrumbs":5,"title":2},"24":{"body":44,"breadcrumbs":5,"title":2},"25":{"body":53,"breadcrumbs":6,"title":3},"26":{"body":23,"breadcrumbs":5,"title":2},"27":{"body":24,"breadcrumbs":5,"title":2},"28":{"body":99,"breadcrumbs":10,"title":7},"29":{"body":8,"breadcrumbs":6,"title":3},"3":{"body":12,"breadcrumbs":3,"title":2},"30":{"body":33,"breadcrumbs":5,"title":2},"31":{"body":76,"breadcrumbs":6,"title":3},"32":{"body":3,"breadcrumbs":6,"title":3},"33":{"body":0,"breadcrumbs":7,"title":3},"34":{"body":97,"breadcrumbs":5,"title":1},"35":{"body":28,"breadcrumbs":5,"title":1},"36":{"body":28,"breadcrumbs":6,"title":2},"37":{"body":38,"breadcrumbs":6,"title":2},"38":{"body":44,"breadcrumbs":6,"title":2},"39":{"body":53,"breadcrumbs":7,"title":3},"4":{"body":0,"breadcrumbs":2,"title":1},"40":{"body":23,"breadcrumbs":6,"title":2},"41":{"body":24,"breadcrumbs":6,"title":2},"42":{"body":99,"breadcrumbs":11,"title":7},"43":{"body":8,"breadcrumbs":7,"title":3},"44":{"body":33,"breadcrumbs":6,"title":2},"45":{"body":76,"breadcrumbs":7,"title":3},"46":{"body":3,"breadcrumbs":7,"title":3},"47":{"body":0,"breadcrumbs":7,"title":3},"48":{"body":97,"breadcrumbs":5,"title":1},"49":{"body":28,"breadcrumbs":5,"title":1},"5":{"body":271,"breadcrumbs":2,"title":1},"50":{"body":28,"breadcrumbs":6,"title":2},"51":{"body":38,"breadcrumbs":6,"title":2},"52":{"body":44,"breadcrumbs":6,"title":2},"53":{"body":53,"breadcrumbs":7,"title":3},"54":{"body":23,"breadcrumbs":6,"title":2},"55":{"body":24,"breadcrumbs":6,"title":2},"56":{"body":99,"breadcrumbs":11,"title":7},"57":{"body":8,"breadcrumbs":7,"title":3},"58":{"body":33,"breadcrumbs":6,"title":2},"59":{"body":76,"breadcrumbs":7,"title":3},"6":{"body":76,"breadcrumbs":2,"title":1},"60":{"body":3,"breadcrumbs":7,"title":3},"61":{"body":29,"breadcrumbs":6,"title":2},"62":{"body":61,"breadcrumbs":6,"title":2},"63":{"body":29,"breadcrumbs":6,"title":2},"64":{"body":77,"breadcrumbs":7,"title":2},"65":{"body":6,"breadcrumbs":8,"title":4},"66":{"body":15,"breadcrumbs":6,"title":3},"67":{"body":21,"breadcrumbs":3,"title":0},"68":{"body":32,"breadcrumbs":5,"title":2},"69":{"body":29,"breadcrumbs":5,"title":2},"7":{"body":152,"breadcrumbs":7,"title":6},"70":{"body":23,"breadcrumbs":6,"title":3},"71":{"body":17,"breadcrumbs":5,"title":2},"72":{"body":41,"breadcrumbs":5,"title":2},"73":{"body":30,"breadcrumbs":6,"title":3},"74":{"body":43,"breadcrumbs":5,"title":2},"75":{"body":19,"breadcrumbs":6,"title":3},"76":{"body":23,"breadcrumbs":7,"title":4},"77":{"body":17,"breadcrumbs":7,"title":4},"78":{"body":31,"breadcrumbs":6,"title":3},"79":{"body":105,"breadcrumbs":5,"title":2},"8":{"body":4,"breadcrumbs":5,"title":3},"80":{"body":98,"breadcrumbs":4,"title":1},"81":{"body":38,"breadcrumbs":6,"title":3},"82":{"body":15,"breadcrumbs":6,"title":3},"83":{"body":40,"breadcrumbs":5,"title":2},"84":{"body":67,"breadcrumbs":6,"title":3},"85":{"body":11,"breadcrumbs":6,"title":3},"86":{"body":31,"breadcrumbs":7,"title":3},"87":{"body":105,"breadcrumbs":6,"title":2},"88":{"body":98,"breadcrumbs":5,"title":1},"89":{"body":38,"breadcrumbs":7,"title":3},"9":{"body":28,"breadcrumbs":4,"title":2},"90":{"body":15,"breadcrumbs":7,"title":3},"91":{"body":40,"breadcrumbs":6,"title":2},"92":{"body":67,"breadcrumbs":7,"title":3},"93":{"body":11,"breadcrumbs":7,"title":3},"94":{"body":31,"breadcrumbs":8,"title":3},"95":{"body":105,"breadcrumbs":7,"title":2},"96":{"body":98,"breadcrumbs":6,"title":1},"97":{"body":38,"breadcrumbs":8,"title":3},"98":{"body":15,"breadcrumbs":8,"title":3},"99":{"body":40,"breadcrumbs":7,"title":2}},"docs":{"0":{"body":"Packeton - Private PHP package repository for vendors. Documentation docs.packeton.org","breadcrumbs":"Overview » Introduction","id":"0","title":"Introduction"},"1":{"body":"Compatible with Composer API v2, bases on Symfony 6. Support update webhook for GitHub, Gitea, Bitbucket and GitLab or custom format. Customers user and ACL groups and limit access by vendor and versions. Composer Proxies and Mirroring. Generic Packeton webhooks Allow to freeze updates for the new releases after expire a customers license. Mirroring for packages zip files and downloads it's from your host. Credentials and Authentication http-basic config or ssh keys. Support monolithic repositories, like symfony/symfony Pull Request composer.lock change review. OAuth2 GitHub, Bitbucket, GitLab/Gitea and Other Integrations. Security Monitoring. Milty sub repositories.","breadcrumbs":"Overview » Main Features","id":"1","title":"Main Features"},"10":{"body":"All env variables is optional. By default, Packeton uses an SQLite database and build-in redis service, but you can overwrite it by env REDIS_URL and DATABASE_URL. The all app data is stored in the VOLUME /data APP_SECRET - Must be static, used for encrypt SSH keys in database. The value is generated automatically, see .env in the data volume. APP_COMPOSER_HOME - composer home, default /data/composer DATABASE_URL - Database DSN, default sqlite:////data/app.db. Example for postgres \"postgresql://app:pass@127.0.0.1:5432/app?serverVersion=14&charset=utf8\" PACKAGIST_DIST_PATH - Default /data/zipball, path to storage zipped versions REDIS_URL - Redis DB, default redis://localhost PACKAGIST_DIST_HOST - Hostname, (auto) default use the current host header in the request. Overwrite packagist host (example https://packagist.youcomany.org). Used for downloading the mirroring zip packages. (The host add into dist url for composer metadata). The default value is define dynamically from the header Host. TRUSTED_PROXIES - Ips for Reverse Proxy. See Symfony docs PUBLIC_ACCESS - Allow anonymous users access to read packages metadata, default: false MAILER_DSN - Mailer for reset password, default disabled MAILER_FROM - Mailer from ADMIN_USER Creating admin account, by default there is no admin user created so you won't be able to login to the packagist. To create an admin account you need to use environment variables to pass in an initial username and password (ADMIN_PASSWORD, ADMIN_EMAIL). ADMIN_PASSWORD - used together with ADMIN_USER ADMIN_EMAIL - used together with ADMIN_USER PRIVATE_REPO_DOMAIN_LIST - Save ssh fingerprints to known_hosts for this domain. VOLUME The all app data is stored in the VOLUME /data","breadcrumbs":"Using docker » Docker Environment","id":"10","title":"Docker Environment"},"100":{"body":"By default, all new packages are automatically enabled and added to your repository when you run composer update. However, you can enable strict mode to use only approved packages and avoid including untrusted packages in your metadata. This can be useful in preventing dependency confusion attacks, especially if you use a 3rd-party Composer repository like https://satis.oroinc.com/. For more information on preventing dependency hacking, please see dependency confusion To enable strict mode, go to the Proxy Settings page and select Composer Proxies -> Packagist (or any other name) -> Settings. strict Next, go to the View Proxy page and click the \"Mass Mirror Packages\" button. strict","breadcrumbs":"Administration » Mirroring Packages » Strict mode » Manual Approval of Dependencies","id":"100","title":"Manual Approval of Dependencies"},"101":{"body":"Use the following configuration: packeton: mirrors: youname: url: https://repo.example.org public_access: true strict","breadcrumbs":"Administration » Mirroring Packages » Strict mode » Mirror Public Access","id":"101","title":"Mirror Public Access"},"102":{"body":"Packeton may support multiple methods of authenticating users. It can additionally be extended to support custom authentication schemes.","breadcrumbs":"User Authentication » User Authentication","id":"102","title":"User Authentication"},"103":{"body":"Included in packeton is support for authenticating users via: A username and password. An email address and password. But possible to enable LDAP only via configuration, see ldap authentication","breadcrumbs":"User Authentication » Web User authentication","id":"103","title":"Web User authentication"},"104":{"body":"Packeton is support API authentication only with api token. Password usage is not allowed. You can see api token in thr user profile menu. Support for authenticating users via: HTTP Basic Authentication (username and api token) Short query param token = username:apiToken Default packagist hook API (query params: username = username, apiToken = apiToken) Your customer needs to authenticate to access their Composer repository: The simplest way to provide your credentials is providing your set of credentials inline with the repository specification such as: { \"repositories\": [ { \"type\": \"composer\", \"url\": \"https://:@example.org\" } ]\n} When you don't want to hard code your credentials into your composer.json, you can set up it global. composer config --global --auth http-basic.example.org username api_token Example API call. curl https://example.com/packages/list.json -u \"username:apiToken\" curl https://example.com/packages/list.json?token=username:apiToken","breadcrumbs":"User Authentication » Composer API authentication","id":"104","title":"Composer API authentication"},"105":{"body":"By default, packeton is storage api tokens in database for each user. But when user loaded from custom user provider, like LDAP need to enable JWT configuration to use API. So Packeton can be configured with a non-standard login type to support JSON Web Tokens . The JSON Web Token integration in Packeton uses the Firebase library . Also, JWT authentication can be enabled only for API. Add yaml configuration file to path config/packages/, for example config/packages/jwt.yaml to enable it. packeton: jwt_authentication: private_key: '%kernel.project_dir%/var/jwt/eddsa-key.pem' public_key: '%kernel.project_dir%/var/jwt/eddsa-public.pem' Full configurations: # config/packages/config/packages/jwt.yaml\npacketon: jwt_authentication: private_key: '%kernel.project_dir%/var/jwt/eddsa-key.pem' # required for token sign public_key: '%kernel.project_dir%/var/jwt/eddsa-public.pem' # required for token verification passphrase: ~ algo: EdDSA # Sign algo, here libsodium EdDSA","breadcrumbs":"User Authentication » JWT Configuration » JWT API Authentication","id":"105","title":"JWT API Authentication"},"106":{"body":"bin/console packagist:jwt:generate-keypair bin/console packagist:jwt:generate-keypair --overwrite Available options: --overwrite will overwrite your keys if they already exist. If keys already exists, a warning message will be raised to prevent you from overwriting your keys accidentally.","breadcrumbs":"User Authentication » JWT Configuration » Generate the public/private keys","id":"106","title":"Generate the public/private keys"},"107":{"body":"JWT Token is never expire. It was done for compatibility with composer basic HTTP authorization. Each time the api is called, Packeton is checked that the user exists in the database and that he has the same set of permissions and roles.","breadcrumbs":"User Authentication » JWT Configuration » JWT Token TTL.","id":"107","title":"JWT Token TTL."},"108":{"body":"We support all algos from Firebase lib: HMAC, OpenSSL RSA, OpenSSL Rsa, HMAC, EdDSA algorithms generate invariant tokens, i.e. the value of the token will be constant for the same user. It might be convenient as the app does not store the generated tokens. Example how to change algo: packeton: jwt_authentication: ... algo: RS256 # RSA 256","breadcrumbs":"User Authentication » JWT Configuration » Digital signatures algos.","id":"108","title":"Digital signatures algos."},"109":{"body":"Example, how to generate an RSA private key, key.pem - private key. public.pem - public openssl genrsa -out key.pem 2048\nopenssl rsa -in key.pem -outform PEM -pubout -out public.pem Example, how to generate an ES256 (elliptic curve) key pairs. openssl ecparam -name prime256v1 -genkey -noout -out key.pem\nopenssl ec -in key.pem -pubout -out public.pem","breadcrumbs":"User Authentication » JWT Configuration » Generating keys using OpenSSL","id":"109","title":"Generating keys using OpenSSL"},"11":{"body":"The typical example docker-compose.yml version: '3.6' services: packeton: image: packeton/packeton:latest container_name: packeton hostname: packeton environment: ADMIN_USER: admin ADMIN_PASSWORD: 123456 ADMIN_EMAIL: admin@example.com DATABASE_URL: mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4 ports: - '127.0.0.1:8080:80' volumes: - .docker:/data By default, the container starts the supervisor, which is used to run other tasks: nginx, redis, php-fpm, cron, however, you can start one service per container. See docker-compose-prod.yml example: version: '3.9' x-volumes: &default-volume volumes: - app-data:/data - app-var:/var/www/packagist/var x-restart-policy: &restart_policy restart: unless-stopped x-environment: &default-environment REDIS_URL: redis://redis DATABASE_URL: \"postgresql://packeton:pack123@postgres:5432/packeton?serverVersion=14&charset=utf8\" SKIP_INIT: 1 services: redis: image: redis:7-alpine hostname: redis <<: *restart_policy volumes: - redis-data:/data postgres: image: postgres:14-alpine hostname: postgres <<: *restart_policy volumes: - postgres-data:/var/lib/postgresql/data environment: POSTGRES_USER: packeton POSTGRES_PASSWORD: pack123 POSTGRES_DB: packeton php-fpm: image: packeton/packeton:latest hostname: php-fpm command: ['php-fpm', '-F'] <<: *restart_policy <<: *default-volume environment: <<: *default-environment SKIP_INIT: 0 WAIT_FOR_HOST: 'postgres:5432' depends_on: - \"postgres\" - \"redis\" nginx: image: packeton/packeton:latest hostname: nginx ports: - '127.0.0.1:8088:80' <<: *restart_policy <<: *default-volume command: > bash -c 'sed s/_PHP_FPM_HOST_/php-fpm:9000/g < docker/nginx/nginx-tpl.conf > /etc/nginx/nginx.conf && nginx' environment: <<: *default-environment WAIT_FOR_HOST: 'php-fpm:9000' depends_on: - \"php-fpm\" worker: image: packeton/packeton:latest hostname: packeton-worker command: ['bin/console', 'packagist:run-workers', '-v'] user: www-data <<: *restart_policy <<: *default-volume environment: <<: *default-environment WAIT_FOR_HOST: 'php-fpm:9000' depends_on: - \"php-fpm\" cron: image: packeton/packeton:latest hostname: packeton-cron command: ['bin/console', 'okvpn:cron', '--demand', '--time-limit=3600'] user: www-data <<: *restart_policy <<: *default-volume environment: <<: *default-environment WAIT_FOR_HOST: 'php-fpm:9000' depends_on: - \"php-fpm\" volumes: redis-data: postgres-data: app-data: app-var:","breadcrumbs":"Using docker » User docker compose","id":"11","title":"User docker compose"},"110":{"body":"You can run command packagist:user:manager to show the api token: bin/console packagist:user:manager admin --show-token --token-format=jwt Or you can found api token on your profile page. Keys","breadcrumbs":"User Authentication » JWT Configuration » Obtain the token","id":"110","title":"Obtain the token"},"111":{"body":"Simply use the JWT, like standard API token for composer api. Cache LDAP user loading. Since 2.0 composer downloads all packages in parallel, it may run more 12 request at the same time. To prevent calls external LDAP provider each time for JWT token verify, the obtained LDAP user object placed to cache with 60 sec TTL.","breadcrumbs":"User Authentication » JWT Configuration » Use the token","id":"111","title":"Use the token"},"112":{"body":"You can enable LDAP authenticating only on configuration level. Packeton has pre-installed Symfony LDAP component. Add the file config/packages/ldap.yaml to enable LDAP with following content. See LDAP in Symfony Docs parameters: default_login_provider: 'form_login_ldap' default_login_options: provider: all_users login_path: /login use_forward: false check_path: /login failure_path: null service: Symfony\\Component\\Ldap\\Ldap dn_string: 'uid={username},dc=example,dc=com' services: Symfony\\Component\\Ldap\\Ldap: arguments: ['@Symfony\\Component\\Ldap\\Adapter\\ExtLdap\\Adapter'] tags: - ldap Symfony\\Component\\Ldap\\Adapter\\ExtLdap\\Adapter: arguments: - host: ldap.forumsys.com port: 389 security: providers: users_ldap: ldap: service: Symfony\\Component\\Ldap\\Ldap base_dn: dc=example,dc=com search_dn: \"cn=read-only-admin,dc=example,dc=com\" search_password: password default_roles: ROLE_MAINTAINER uid_key: uid all_users: chain: providers: ['packagist', 'users_ldap'] Here is working example where used test ldap.forumsys.com server https://www.forumsys.com/2022/05/10/online-ldap-test-server/ Using LDAP integration does not prevent you from creating user manually from CLI and assign more accessible roles. At the same LDAP password validation will be done on LDAP server side, because CheckLdapCredentialsListener has higher priority loading than default check listener. Therefore, if user is not enable in LDAP - it will not able login to packeton.","breadcrumbs":"User Authentication » LDAP Configuration » Authenticating against an LDAP server","id":"112","title":"Authenticating against an LDAP server"},"113":{"body":"Packeton use Symfony Chain User Provider to lookup users. If you want to use customer user restriction by vendors and versions, packagist user provider must load before ldap. security: providers: users_ldap: ldap: ... all_users: chain: providers: ['packagist', 'users_ldap'] # Load user/roles form default packagist and if not found - use ldap user providers: ['users_ldap', 'packagist'] # packagist users will be ignore","breadcrumbs":"User Authentication » LDAP Configuration » User providers priority.","id":"113","title":"User providers priority."},"114":{"body":"You can use more 1 user providers: security: providers: users_ldap: ldap: service: Symfony\\Component\\Ldap\\Ldap base_dn: dc=example,dc=com search_dn: \"cn=read-only-admin,dc=example,dc=com\" filter: \"(&(objectclass=groupOfUniqueNames)(ou=scientists)(uniqueMember=uid={username},dc=example,dc=com))\" search_password: password default_roles: ROLE_MAINTAINER uid_key: uid users_ldap_admin: ldap: service: Symfony\\Component\\Ldap\\Ldap base_dn: dc=example,dc=com search_dn: \"cn=read-only-admin,dc=example,dc=com\" filter: \"(&(objectclass=groupOfUniqueNames)(ou=mathematicians)(uniqueMember=uid={username},dc=example,dc=com))\" search_password: password default_roles: ROLE_ADMIN uid_key: uid all_users: chain: providers: ['packagist', 'users_ldap', 'users_ldap_admin'] Here test example where exists two Groups (ou) that include: ou=mathematicians,dc=example,dc=com - assign role ROLE_ADMIN ou=scientists,dc=example,dc=com - assign role ROLE_MAINTAINER","breadcrumbs":"User Authentication » LDAP Configuration » Load different roles from LDAP.","id":"114","title":"Load different roles from LDAP."},"115":{"body":"By default, packeton is storage api token in database for each user. But if the user was loaded by custom external users' provider, but from the database, you will need enable JWT configuration. See JWT Configuration","breadcrumbs":"User Authentication » LDAP Configuration » API authentication with LDAP users.","id":"115","title":"API authentication with LDAP users."},"116":{"body":"You can use docker volume to share own configuration to application. ... volumes: - .docker:/data - ${PWD}/ldap.yaml:/var/www/packagist/config/packages/ldap.yaml","breadcrumbs":"User Authentication » LDAP Configuration » Enable LDAP for docker runtime.","id":"116","title":"Enable LDAP for docker runtime."},"117":{"body":"By default, Packeton stores packages archives on the local filesystem. But you can easily configure the S3 using league/flysystem-bundle. For docker env, please set env vars. STORAGE_SOURCE=s3\nSTORAGE_AWS_BUCKET=packeton-bucket\nSTORAGE_AWS_PREFIX=packeton\nSTORAGE_AWS_ARTIFACT_PREFIX=artifact STORAGE_AWS_ARGS='{\"endpoint\": \"https://s3.waw.io.cloud.ovh.net\", \"accessKeyId\": \"xxx\", \"accessKeySecret\": \"xxx\", \"region\": \"waw\"}' Sometimes for Artifact Repository requires direct access to files from the archive, so to improve performance and reduces count of S3 API requests, the all archives are cached on the local filesystem too. If you need to use the other provider, like Google Cloud, you may add config file to config/packages or use config.yaml in data docker dir. flysystem: storages: s3_v2.storage: adapter: 'asyncaws' options: client: 'packeton.s3.storage' bucket: '%env(STORAGE_AWS_BUCKET)%' prefix: '%env(STORAGE_AWS_PREFIX)%' s3_v2.artifact: adapter: 'asyncaws' options: client: 'packeton.s3.storage' bucket: '%env(STORAGE_AWS_BUCKET)%' prefix: '%env(STORAGE_AWS_ARTIFACT_PREFIX)%' gcloud.storage: adapter: 'gcloud' options: client: 'gcloud_client_service' bucket: 'bucket_name' prefix: 'optional/path/prefix' gcloud.artifact: adapter: 'gcloud' options: client: 'gcloud_client_service' bucket: 'bucket_name' prefix: 'optional/path/artifact' parameters: env(STORAGE_AWS_BUCKET): 'packeton-bucket' env(STORAGE_AWS_PREFIX): 'packeton' env(STORAGE_AWS_ARGS): '[]' env(STORAGE_AWS_ARTIFACT_PREFIX): 'artifact' services: packeton.s3.storage: class: AsyncAws\\S3\\S3Client arguments: $configuration: '%env(json:STORAGE_AWS_ARGS)%' $httpClient: '@Symfony\\Contracts\\HttpClient\\HttpClientInterface' $logger: '@logger' gcloud_client_service: class: Google\\Cloud\\Storage\\StorageClient arguments: - { keyFilePath: 'path/to/keyfile.json' } STORAGE_SOURCE=s3_v2\nSTORAGE_SOURCE=gcloud","breadcrumbs":"S3 Storage Provider » S3 Storage Provider","id":"117","title":"S3 Storage Provider"},"118":{"body":"If you are distributing packages to your customers, you may want to create a separate domain for Composer metadata-only to hide the default web interface and login page. Add following lines to you configuration. config.yaml or config/packages/*.yaml packeton: web_protection: ## Multi host protection, disable web-ui if host !== app.example.com and ips != 127.0.0.1, 10.9.1.0/24 ## But the repo metadata will be available for all hosts and ips. repo_hosts: ['*', '!app.example.com'] allow_ips: '127.0.0.1, 10.9.1.0/24' status_code: 402 custom_page: > # Custom landing non-auth page. Path or HTML 402 Payment Required 402 Payment Required
nginx Where custom_page html content or path to html page. Here all hosts will be hidden under this page (if ip is not match or host != app.example.com). app.example.com - this is host for default Web-UI.","breadcrumbs":"Custom landing page » Custom landing page","id":"118","title":"Custom landing page"},"119":{"body":"web_protection: repo_hosts: ['repo.example.com'] Here Web-UI will be hidden for repo_hosts host repo.example.com.","breadcrumbs":"Custom landing page » Example 2","id":"119","title":"Example 2"},"12":{"body":"Clone repository git clone https://github.com/vtsykun/packeton.git /var/www/packeton/\ncd /var/www/packeton/ Run docker-compose build docker-compose build # start container.\ndocker-compose up -d # Run with single supervisor container docker-compose up -f docker-compose-prod.yml -d # Or split","breadcrumbs":"Using docker » Build and run docker container with docker-compose","id":"12","title":"Build and run docker container with docker-compose"},"120":{"body":"Security Monitoring allow to send notifications when found a security problem in your composer.lock. By default, used packagist.org database. Packeton is automatically check the main branch of every repository if the composer.lock is exists. You need to configure notifications webhook to receive notification if found a new security issue. Also, you may see list of security advisories in the package page. logo","breadcrumbs":"Security Monitoring » Security Monitoring","id":"120","title":"Security Monitoring"},"121":{"body":"Go to Webhook page and click the \"Add Webhook\". Please fill the form. Form Description Name Any name Url Target url address. For example https://api.telegram.org/bot${secrets.TOKEN}/sendMessage Method POST Request options Symfony HTTP client options (like custom headers, auth) JSON Payload Twig render payload For example request payload for telegram. It will send JSON request, because response is array {% set text = \"New security issue *#{package.name}*\\n\\n\" %}\n{% for advisory in advisories %} {% set text = text ~ \"#{advisory.title}\\nPackage: *#{advisory.packageName}* #{advisory.version}\\n\" %} {% set text = text ~ (advisory.cve and advisory.link ? \"[#{advisory.cve}](#{advisory.link})\\n\" : \"Advisory: #{advisory.advisoryId}\\n\") %} {% set text = text ~ \"Reported at: #{advisory.reportedAt}\\n\\n\" %}\n{% endfor %} {% set response = { 'chat_id': '${secrets.CHART_ID}', 'text': text, 'parse_mode': 'Markdown'\n} %} {% return response %} Twig vars: advisories - list of advisories Composer\\Advisory\\SecurityAdvisory package - package object. Where ${secrets.CHART_ID} ${secrets.TOKEN} replace with secrets or hardcode this params. See webhooks docs.","breadcrumbs":"Security Monitoring » Configure Webhook Notifications","id":"121","title":"Configure Webhook Notifications"},"122":{"body":"Packeton import provide interface to fast mass import all private packages from your own composer repository, like Satis/Packagist. also you may use oauth2 integration to import all packages from your VCS hosting import Where Glob package filter - List of Glob to filter by package vendor name. Example input value: okvpn/*\norg1/* Select only packages (default all packages in the repository) - used if composer repository does not provide API to fetch list of all packages. Put your composer.json, composer.lock, composer info output or packages names separated by spaces or line break Example input value: sebastian/cli-parser 2.0.0 Library for parsing CLI options\nsebastian/code-unit 2.0.0 Collection of value objects that represent the PHP code units\nsebastian/code-unit-reverse-lookup 3.0.0 Looks up which function or method a line of code belongs to\nsebastian/comparator 5.0.1 Provides the functionality to compare PHP values for equality\nsebastian/complexity 3.0.1 Library for calculating the complexity of PHP code units\nsebastian/diff 5.0.3 Diff implementation\nsebastian/environment 6.0.1 Provides functionality to handle HHVM/PHP environments\nsebastian/exporter 5.0.0 Provides the functionality to export PHP variables for visualization\nsebastian/global-state 6.0.1 Snapshotting of global state\nsebastian/lines-of-code 2.0.1 Library for counting the lines of code in PHP source code Clone preference - used to select URL format. SSH or HTTPs clone.","breadcrumbs":"Migrate from Satis » Migrate from Packagist.com / Satis","id":"122","title":"Migrate from Packagist.com / Satis"},"123":{"body":"","breadcrumbs":"OAuth2 Integrations » OAuth2 and Sync integrations","id":"123","title":"OAuth2 and Sync integrations"},"124":{"body":"Pull Request review Login Restriction GitHub Setup GitHub App Setup GitLab Setup Gitea Setup Bitbucket Setup","breadcrumbs":"OAuth2 Integrations » Table of content","id":"124","title":"Table of content"},"125":{"body":"To enable OAuth2 integrations you need to add following configuration packeton: integrations: github: # Alias name allow_login: true # default false allow_register: false # default false default_roles: ['ROLE_USER', 'ROLE_MAINTAINER', 'ROLE_GITLAB'] clone_preference: 'api' repos_synchronization: true disable_hook_repos: false # disabled auto setup webhook disable_hook_org: false svg_logo: ~ #
packeton:
integrations:
github: # Alias name
@@ -2664,8 +2664,8 @@ GitLab
GitLab Groups Webhooks notices
A group webhooks needed for synchronization a new package.
They are triggered by events that occur across all projects in the group.
-This feature enabled only for Premium / EE / Gold paid plan, but it can be replaced with GitLab Packagist Integration
-You must manually setup this integration.
+This feature is enabled only for Premium / EE / Gold paid plan, but it can be replaced with GitLab Packagist Integration
+You must manually set up this integration.
Where token you can find on the packeton integration view page. The token must have whk
prefix
to find related integration access token.
@@ -2717,7 +2717,7 @@
-
Use obtained clinent_id
, client_secret
to create configuration in yaml. For docker installation you may use config.yaml
file in docker volume.
+Use obtained client_id
, client_secret
to create configuration in yaml. For docker installation you may use config.yaml
file in docker volume.
packeton:
integrations:
github: # any alias name
@@ -2727,25 +2727,34 @@
GitHub App Integration
-
GitHub App Integration is alternative of GitHub OAuth2. To create GitHub go to
-Settings / Developer settings / GitHub Apps and click New GitHub App.
-Use the next "Callback URL / Redirect URL".
-Redirect Urls:
-https://example.com/oauth2/{alias}/install
-https://example.com/oauth2/{alias}/check
+GitHub App Integration is alternative of GitHub OAuth2.
+To create GitHub go to: Settings / Developer settings / GitHub Apps and click New GitHub App
.
+
+- Enter a GitHub App name: Private Packeton.
+- Enter a homepage url: https://packeton.example.com for example.
+- Click
Add Callback URL
and use the next "Callback URL / Redirect URL".
+
+https://packeton.example.com/oauth2/{alias}/install
+https://packeton.example.com/oauth2/{alias}/check
-The webhooks URL maybe any. We don't use it and setup webhooks per repository or choice organization.
-Select Permissions:
-- Webhooks read-write (Repository permissions)
-- Metadata (Repository permissions)
-- Pull requests read-write (Repository permissions)
-- Webhooks read-write (Organization permissions)
-- Members read (Organization permissions) - optional
+- Uncheck webhook active checkbox
+
+Select Repository permissions:
+
+- Content: read-only
+- Webhooks: read-write
+- Metadata: read-only (already selected)
+- Pull requests read-write
+
+Select Organization permissions:
+
+- Webhooks: read-write
+- Members: read (optional)
After creating App go to App view page and find app_id
and generate a "Private Key"
@@ -2761,12 +2770,15 @@
After install you will see installation_id
on URL address. For example https://github.com/settings/installations/38069000
-Now go to Packeton integration page and click Install Integration. When click to Connect under you githubapp configuration.
-To finish setup Go to Packeton integration view page / Settings and provider installation_id
in the form
+Now go to Packeton integration
page and click Install Integration
.
+When click to Connect
under you github
configuration.
+
+To finish setup Go to Packeton integration
view page / Settings and provider installation_id
in the form
GitLab Integration Setup
Go to you GitLab account preferences (https://gitlab.example.com/-/profile/preferences
) and select "Applications"
diff --git a/searchindex.js b/searchindex.js
index eabe3402..0907e225 100644
--- a/searchindex.js
+++ b/searchindex.js
@@ -1 +1 @@
-Object.assign(window.search, {"doc_urls":["index.html#introduction","index.html#main-features","index.html#compare-private-packagist-with-packeton","installation.html#install-and-run","installation.html#installation","installation.html#requirements","installation.html#configuration","installation.html#ssh-key-access-and-composer-oauth-token","installation-docker.html#install-and-run-in-docker","installation-docker.html#quick-start","installation-docker.html#docker-environment","installation-docker.html#user-docker-compose","installation-docker.html#build-and-run-docker-container-with-docker-compose","reverse-proxy.html#using-a-reverse-proxy","reverse-proxy.html#reverse-proxy-configuration-examples","usage/index.html#administration","usage/index.html#table-of-content","usage/index.html#application-roles","usage/api.html#api-documentation","webhook.html#generic-packeton-webhooks","webhook.html#introduction","webhook.html#examples","webhook.html#twig-variables","webhook.html#telegram-notification","webhook.html#slack-notification","webhook.html#use-url-placeholder","webhook.html#interrupt-request","webhook.html#nesting-webhook","webhook.html#jira-create-a-new-release-and-set-fix-version","webhook.html#http-request-from-code","webhook.html#external-request","webhook.html#gitlab-auto-webhook","webhook.html#new-twig-functions","webhook.html#generic-packeton-webhooks","webhook.html#introduction","webhook.html#examples","webhook.html#twig-variables","webhook.html#telegram-notification","webhook.html#slack-notification","webhook.html#use-url-placeholder","webhook.html#interrupt-request","webhook.html#nesting-webhook","webhook.html#jira-create-a-new-release-and-set-fix-version","webhook.html#http-request-from-code","webhook.html#external-request","webhook.html#gitlab-auto-webhook","webhook.html#new-twig-functions","webhook.html#generic-packeton-webhooks","webhook.html#introduction","webhook.html#examples","webhook.html#twig-variables","webhook.html#telegram-notification","webhook.html#slack-notification","webhook.html#use-url-placeholder","webhook.html#interrupt-request","webhook.html#nesting-webhook","webhook.html#jira-create-a-new-release-and-set-fix-version","webhook.html#http-request-from-code","webhook.html#external-request","webhook.html#gitlab-auto-webhook","webhook.html#new-twig-functions","webhook/webhook-secrets.html#manage-secrets","webhook/webhook-secrets.html#encrypt-secrets","webhook/webhook-secrets.html#usage-secrets","webhook/wh-security.html#webhook-security","webhook/wh-test.html#test-webhook-twig-payload","usage/update-packages.html#how-to-auto-update-packages","usage/update-packages.html#into","usage/update-packages.html#bitbucket-webhooks","usage/update-packages.html#gitlab-service","usage/update-packages.html#gitlab-group-hooks","usage/update-packages.html#github-webhooks","usage/update-packages.html#gitea-webhooks","usage/update-packages.html#manual-hook-setup","usage/customers.html#customer-users","usage/customers.html#create-customer-user","usage/credential.html#ssh-credential-and-composer-auth","usage/credential.html#using-ui-credential-manager","usage/mirroring.html#mirroring-and-composer-proxies","usage/mirroring.html#main-features","usage/mirroring.html#configuration","usage/mirroring.html#metadata-proxy-specification","usage/mirroring.html#default-sync-intervals","usage/mirroring.html#commands-for-debug","usage/mirroring.html#manual-approval-of-dependencies","usage/mirroring.html#mirror-public-access","usage/mirroring.html#mirroring-and-composer-proxies","usage/mirroring.html#main-features","usage/mirroring.html#configuration","usage/mirroring.html#metadata-proxy-specification","usage/mirroring.html#default-sync-intervals","usage/mirroring.html#commands-for-debug","usage/mirroring.html#manual-approval-of-dependencies","usage/mirroring.html#mirror-public-access","usage/mirroring.html#mirroring-and-composer-proxies","usage/mirroring.html#main-features","usage/mirroring.html#configuration","usage/mirroring.html#metadata-proxy-specification","usage/mirroring.html#default-sync-intervals","usage/mirroring.html#commands-for-debug","usage/mirroring.html#manual-approval-of-dependencies","usage/mirroring.html#mirror-public-access","authentication.html#user-authentication","authentication.html#web-user-authentication","authentication.html#composer-api-authentication","authentication-jwt.html#jwt-api-authentication","authentication-jwt.html#generate-the-publicprivate-keys","authentication-jwt.html#jwt-token-ttl","authentication-jwt.html#digital-signatures-algos","authentication-jwt.html#generating-keys-using-openssl","authentication-jwt.html#obtain-the-token","authentication-jwt.html#use-the-token","authentication-ldap.html#authenticating-against-an-ldap-server","authentication-ldap.html#user-providers-priority","authentication-ldap.html#load-different-roles-from-ldap","authentication-ldap.html#api-authentication-with-ldap-users","authentication-ldap.html#enable-ldap-for-docker-runtime","usage/storage.html#s3-storage-provider","usage/custom-page.html#custom-landing-page","usage/custom-page.html#example-2","usage/security-monitoring.html#security-monitoring","usage/security-monitoring.html#configure-webhook-notifications","usage/migrate.html#migrate-from-packagistcom--satis","oauth2.html#oauth2-and-sync-integrations","oauth2.html#table-of-content","oauth2.html#base-configuration-reference","oauth2.html#docker-env","oauth2.html#supported-3-d-provider","oauth2.html#github","oauth2.html#gitlab","oauth2.html#gitea","oauth2.html#bitbucket","pull-request-review.html#pull-request-composer-lock-review","pull-request-review.html#configure-pull-request-review","oauth2/github-oauth.html#github-oauth2-setup","oauth2/githubapp.html#github-app-integration","oauth2/gitlab-integration.html#gitlab-integration-setup","oauth2/gitea.html#gitea-integration-setup","oauth2/bitbucket.html#bitbucket-integration-setup","oauth2/login-expression.html#limit-loginregister-with-using-expression-lang","oauth2/login-expression.html#custom-twig-function-for-expression-lang","oauth2/login-expression.html#debug-expressions","dev/CONTRIBUTING.html#contributing","dev/CONTRIBUTING.html#1-development-environment","dev/CONTRIBUTING.html#2-get-the-source","dev/CONTRIBUTING.html#3-install-the-dependencies","dev/CONTRIBUTING.html#4-configure-your-env-vars","dev/CONTRIBUTING.html#5-setup-database","dev/CONTRIBUTING.html#6-run-local-webserver","dev/CONTRIBUTING.html#enjoy","dev/configuration.html#configuration-reference"],"index":{"documentStore":{"docInfo":{"0":{"body":8,"breadcrumbs":2,"title":1},"1":{"body":71,"breadcrumbs":3,"title":2},"10":{"body":159,"breadcrumbs":4,"title":2},"100":{"body":67,"breadcrumbs":8,"title":3},"101":{"body":11,"breadcrumbs":8,"title":3},"102":{"body":12,"breadcrumbs":4,"title":2},"103":{"body":19,"breadcrumbs":5,"title":3},"104":{"body":89,"breadcrumbs":5,"title":3},"105":{"body":84,"breadcrumbs":7,"title":3},"106":{"body":24,"breadcrumbs":7,"title":3},"107":{"body":23,"breadcrumbs":7,"title":3},"108":{"body":35,"breadcrumbs":7,"title":3},"109":{"body":44,"breadcrumbs":8,"title":4},"11":{"body":219,"breadcrumbs":5,"title":3},"110":{"body":19,"breadcrumbs":6,"title":2},"111":{"body":42,"breadcrumbs":6,"title":2},"112":{"body":118,"breadcrumbs":8,"title":4},"113":{"body":45,"breadcrumbs":7,"title":3},"114":{"body":61,"breadcrumbs":8,"title":4},"115":{"body":22,"breadcrumbs":8,"title":4},"116":{"body":9,"breadcrumbs":8,"title":4},"117":{"body":135,"breadcrumbs":6,"title":3},"118":{"body":85,"breadcrumbs":6,"title":3},"119":{"body":10,"breadcrumbs":5,"title":2},"12":{"body":34,"breadcrumbs":8,"title":6},"120":{"body":38,"breadcrumbs":4,"title":2},"121":{"body":100,"breadcrumbs":5,"title":3},"122":{"body":151,"breadcrumbs":5,"title":3},"123":{"body":0,"breadcrumbs":5,"title":3},"124":{"body":16,"breadcrumbs":4,"title":2},"125":{"body":212,"breadcrumbs":5,"title":3},"126":{"body":46,"breadcrumbs":4,"title":2},"127":{"body":0,"breadcrumbs":6,"title":4},"128":{"body":9,"breadcrumbs":3,"title":1},"129":{"body":53,"breadcrumbs":3,"title":1},"13":{"body":9,"breadcrumbs":6,"title":3},"130":{"body":10,"breadcrumbs":3,"title":1},"131":{"body":11,"breadcrumbs":3,"title":1},"132":{"body":30,"breadcrumbs":10,"title":5},"133":{"body":58,"breadcrumbs":9,"title":4},"134":{"body":79,"breadcrumbs":7,"title":3},"135":{"body":150,"breadcrumbs":7,"title":3},"136":{"body":89,"breadcrumbs":7,"title":3},"137":{"body":73,"breadcrumbs":7,"title":3},"138":{"body":60,"breadcrumbs":7,"title":3},"139":{"body":102,"breadcrumbs":9,"title":5},"14":{"body":211,"breadcrumbs":7,"title":4},"140":{"body":37,"breadcrumbs":9,"title":5},"141":{"body":55,"breadcrumbs":6,"title":2},"142":{"body":5,"breadcrumbs":2,"title":1},"143":{"body":36,"breadcrumbs":4,"title":3},"144":{"body":16,"breadcrumbs":3,"title":2},"145":{"body":7,"breadcrumbs":4,"title":3},"146":{"body":11,"breadcrumbs":5,"title":4},"147":{"body":5,"breadcrumbs":4,"title":3},"148":{"body":5,"breadcrumbs":5,"title":4},"149":{"body":0,"breadcrumbs":2,"title":1},"15":{"body":6,"breadcrumbs":2,"title":1},"150":{"body":300,"breadcrumbs":4,"title":2},"16":{"body":20,"breadcrumbs":3,"title":2},"17":{"body":60,"breadcrumbs":3,"title":2},"18":{"body":229,"breadcrumbs":5,"title":2},"19":{"body":0,"breadcrumbs":6,"title":3},"2":{"body":194,"breadcrumbs":5,"title":4},"20":{"body":97,"breadcrumbs":4,"title":1},"21":{"body":28,"breadcrumbs":4,"title":1},"22":{"body":28,"breadcrumbs":5,"title":2},"23":{"body":38,"breadcrumbs":5,"title":2},"24":{"body":44,"breadcrumbs":5,"title":2},"25":{"body":53,"breadcrumbs":6,"title":3},"26":{"body":23,"breadcrumbs":5,"title":2},"27":{"body":24,"breadcrumbs":5,"title":2},"28":{"body":99,"breadcrumbs":10,"title":7},"29":{"body":8,"breadcrumbs":6,"title":3},"3":{"body":12,"breadcrumbs":3,"title":2},"30":{"body":33,"breadcrumbs":5,"title":2},"31":{"body":76,"breadcrumbs":6,"title":3},"32":{"body":3,"breadcrumbs":6,"title":3},"33":{"body":0,"breadcrumbs":7,"title":3},"34":{"body":97,"breadcrumbs":5,"title":1},"35":{"body":28,"breadcrumbs":5,"title":1},"36":{"body":28,"breadcrumbs":6,"title":2},"37":{"body":38,"breadcrumbs":6,"title":2},"38":{"body":44,"breadcrumbs":6,"title":2},"39":{"body":53,"breadcrumbs":7,"title":3},"4":{"body":0,"breadcrumbs":2,"title":1},"40":{"body":23,"breadcrumbs":6,"title":2},"41":{"body":24,"breadcrumbs":6,"title":2},"42":{"body":99,"breadcrumbs":11,"title":7},"43":{"body":8,"breadcrumbs":7,"title":3},"44":{"body":33,"breadcrumbs":6,"title":2},"45":{"body":76,"breadcrumbs":7,"title":3},"46":{"body":3,"breadcrumbs":7,"title":3},"47":{"body":0,"breadcrumbs":7,"title":3},"48":{"body":97,"breadcrumbs":5,"title":1},"49":{"body":28,"breadcrumbs":5,"title":1},"5":{"body":271,"breadcrumbs":2,"title":1},"50":{"body":28,"breadcrumbs":6,"title":2},"51":{"body":38,"breadcrumbs":6,"title":2},"52":{"body":44,"breadcrumbs":6,"title":2},"53":{"body":53,"breadcrumbs":7,"title":3},"54":{"body":23,"breadcrumbs":6,"title":2},"55":{"body":24,"breadcrumbs":6,"title":2},"56":{"body":99,"breadcrumbs":11,"title":7},"57":{"body":8,"breadcrumbs":7,"title":3},"58":{"body":33,"breadcrumbs":6,"title":2},"59":{"body":76,"breadcrumbs":7,"title":3},"6":{"body":76,"breadcrumbs":2,"title":1},"60":{"body":3,"breadcrumbs":7,"title":3},"61":{"body":29,"breadcrumbs":6,"title":2},"62":{"body":61,"breadcrumbs":6,"title":2},"63":{"body":29,"breadcrumbs":6,"title":2},"64":{"body":77,"breadcrumbs":7,"title":2},"65":{"body":6,"breadcrumbs":8,"title":4},"66":{"body":15,"breadcrumbs":6,"title":3},"67":{"body":21,"breadcrumbs":3,"title":0},"68":{"body":32,"breadcrumbs":5,"title":2},"69":{"body":29,"breadcrumbs":5,"title":2},"7":{"body":152,"breadcrumbs":7,"title":6},"70":{"body":23,"breadcrumbs":6,"title":3},"71":{"body":17,"breadcrumbs":5,"title":2},"72":{"body":41,"breadcrumbs":5,"title":2},"73":{"body":30,"breadcrumbs":6,"title":3},"74":{"body":43,"breadcrumbs":5,"title":2},"75":{"body":19,"breadcrumbs":6,"title":3},"76":{"body":23,"breadcrumbs":7,"title":4},"77":{"body":17,"breadcrumbs":7,"title":4},"78":{"body":31,"breadcrumbs":6,"title":3},"79":{"body":105,"breadcrumbs":5,"title":2},"8":{"body":4,"breadcrumbs":5,"title":3},"80":{"body":98,"breadcrumbs":4,"title":1},"81":{"body":38,"breadcrumbs":6,"title":3},"82":{"body":15,"breadcrumbs":6,"title":3},"83":{"body":40,"breadcrumbs":5,"title":2},"84":{"body":67,"breadcrumbs":6,"title":3},"85":{"body":11,"breadcrumbs":6,"title":3},"86":{"body":31,"breadcrumbs":7,"title":3},"87":{"body":105,"breadcrumbs":6,"title":2},"88":{"body":98,"breadcrumbs":5,"title":1},"89":{"body":38,"breadcrumbs":7,"title":3},"9":{"body":28,"breadcrumbs":4,"title":2},"90":{"body":15,"breadcrumbs":7,"title":3},"91":{"body":40,"breadcrumbs":6,"title":2},"92":{"body":67,"breadcrumbs":7,"title":3},"93":{"body":11,"breadcrumbs":7,"title":3},"94":{"body":31,"breadcrumbs":8,"title":3},"95":{"body":105,"breadcrumbs":7,"title":2},"96":{"body":98,"breadcrumbs":6,"title":1},"97":{"body":38,"breadcrumbs":8,"title":3},"98":{"body":15,"breadcrumbs":8,"title":3},"99":{"body":40,"breadcrumbs":7,"title":2}},"docs":{"0":{"body":"Packeton - Private PHP package repository for vendors. Documentation docs.packeton.org","breadcrumbs":"Overview » Introduction","id":"0","title":"Introduction"},"1":{"body":"Compatible with Composer API v2, bases on Symfony 6. Support update webhook for GitHub, Gitea, Bitbucket and GitLab or custom format. Customers user and ACL groups and limit access by vendor and versions. Composer Proxies and Mirroring. Generic Packeton webhooks Allow to freeze updates for the new releases after expire a customers license. Mirroring for packages zip files and downloads it's from your host. Credentials and Authentication http-basic config or ssh keys. Support monolithic repositories, like symfony/symfony Pull Request composer.lock change review. OAuth2 GitHub, Bitbucket, GitLab/Gitea and Other Integrations. Security Monitoring. Milty sub repositories.","breadcrumbs":"Overview » Main Features","id":"1","title":"Main Features"},"10":{"body":"All env variables is optional. By default, Packeton uses an SQLite database and build-in redis service, but you can overwrite it by env REDIS_URL and DATABASE_URL. The all app data is stored in the VOLUME /data APP_SECRET - Must be static, used for encrypt SSH keys in database. The value is generated automatically, see .env in the data volume. APP_COMPOSER_HOME - composer home, default /data/composer DATABASE_URL - Database DSN, default sqlite:////data/app.db. Example for postgres \"postgresql://app:pass@127.0.0.1:5432/app?serverVersion=14&charset=utf8\" PACKAGIST_DIST_PATH - Default /data/zipball, path to storage zipped versions REDIS_URL - Redis DB, default redis://localhost PACKAGIST_DIST_HOST - Hostname, (auto) default use the current host header in the request. Overwrite packagist host (example https://packagist.youcomany.org). Used for downloading the mirroring zip packages. (The host add into dist url for composer metadata). The default value is define dynamically from the header Host. TRUSTED_PROXIES - Ips for Reverse Proxy. See Symfony docs PUBLIC_ACCESS - Allow anonymous users access to read packages metadata, default: false MAILER_DSN - Mailer for reset password, default disabled MAILER_FROM - Mailer from ADMIN_USER Creating admin account, by default there is no admin user created so you won't be able to login to the packagist. To create an admin account you need to use environment variables to pass in an initial username and password (ADMIN_PASSWORD, ADMIN_EMAIL). ADMIN_PASSWORD - used together with ADMIN_USER ADMIN_EMAIL - used together with ADMIN_USER PRIVATE_REPO_DOMAIN_LIST - Save ssh fingerprints to known_hosts for this domain. VOLUME The all app data is stored in the VOLUME /data","breadcrumbs":"Using docker » Docker Environment","id":"10","title":"Docker Environment"},"100":{"body":"By default, all new packages are automatically enabled and added to your repository when you run composer update. However, you can enable strict mode to use only approved packages and avoid including untrusted packages in your metadata. This can be useful in preventing dependency confusion attacks, especially if you use a 3rd-party Composer repository like https://satis.oroinc.com/. For more information on preventing dependency hacking, please see dependency confusion To enable strict mode, go to the Proxy Settings page and select Composer Proxies -> Packagist (or any other name) -> Settings. strict Next, go to the View Proxy page and click the \"Mass Mirror Packages\" button. strict","breadcrumbs":"Administration » Mirroring Packages » Strict mode » Manual Approval of Dependencies","id":"100","title":"Manual Approval of Dependencies"},"101":{"body":"Use the following configuration: packeton: mirrors: youname: url: https://repo.example.org public_access: true strict","breadcrumbs":"Administration » Mirroring Packages » Strict mode » Mirror Public Access","id":"101","title":"Mirror Public Access"},"102":{"body":"Packeton may support multiple methods of authenticating users. It can additionally be extended to support custom authentication schemes.","breadcrumbs":"User Authentication » User Authentication","id":"102","title":"User Authentication"},"103":{"body":"Included in packeton is support for authenticating users via: A username and password. An email address and password. But possible to enable LDAP only via configuration, see ldap authentication","breadcrumbs":"User Authentication » Web User authentication","id":"103","title":"Web User authentication"},"104":{"body":"Packeton is support API authentication only with api token. Password usage is not allowed. You can see api token in thr user profile menu. Support for authenticating users via: HTTP Basic Authentication (username and api token) Short query param token = username:apiToken Default packagist hook API (query params: username = username, apiToken = apiToken) Your customer needs to authenticate to access their Composer repository: The simplest way to provide your credentials is providing your set of credentials inline with the repository specification such as: { \"repositories\": [ { \"type\": \"composer\", \"url\": \"https://:@example.org\" } ]\n} When you don't want to hard code your credentials into your composer.json, you can set up it global. composer config --global --auth http-basic.example.org username api_token Example API call. curl https://example.com/packages/list.json -u \"username:apiToken\" curl https://example.com/packages/list.json?token=username:apiToken","breadcrumbs":"User Authentication » Composer API authentication","id":"104","title":"Composer API authentication"},"105":{"body":"By default, packeton is storage api tokens in database for each user. But when user loaded from custom user provider, like LDAP need to enable JWT configuration to use API. So Packeton can be configured with a non-standard login type to support JSON Web Tokens . The JSON Web Token integration in Packeton uses the Firebase library . Also, JWT authentication can be enabled only for API. Add yaml configuration file to path config/packages/, for example config/packages/jwt.yaml to enable it. packeton: jwt_authentication: private_key: '%kernel.project_dir%/var/jwt/eddsa-key.pem' public_key: '%kernel.project_dir%/var/jwt/eddsa-public.pem' Full configurations: # config/packages/config/packages/jwt.yaml\npacketon: jwt_authentication: private_key: '%kernel.project_dir%/var/jwt/eddsa-key.pem' # required for token sign public_key: '%kernel.project_dir%/var/jwt/eddsa-public.pem' # required for token verification passphrase: ~ algo: EdDSA # Sign algo, here libsodium EdDSA","breadcrumbs":"User Authentication » JWT Configuration » JWT API Authentication","id":"105","title":"JWT API Authentication"},"106":{"body":"bin/console packagist:jwt:generate-keypair bin/console packagist:jwt:generate-keypair --overwrite Available options: --overwrite will overwrite your keys if they already exist. If keys already exists, a warning message will be raised to prevent you from overwriting your keys accidentally.","breadcrumbs":"User Authentication » JWT Configuration » Generate the public/private keys","id":"106","title":"Generate the public/private keys"},"107":{"body":"JWT Token is never expire. It was done for compatibility with composer basic HTTP authorization. Each time the api is called, Packeton is checked that the user exists in the database and that he has the same set of permissions and roles.","breadcrumbs":"User Authentication » JWT Configuration » JWT Token TTL.","id":"107","title":"JWT Token TTL."},"108":{"body":"We support all algos from Firebase lib: HMAC, OpenSSL RSA, OpenSSL Rsa, HMAC, EdDSA algorithms generate invariant tokens, i.e. the value of the token will be constant for the same user. It might be convenient as the app does not store the generated tokens. Example how to change algo: packeton: jwt_authentication: ... algo: RS256 # RSA 256","breadcrumbs":"User Authentication » JWT Configuration » Digital signatures algos.","id":"108","title":"Digital signatures algos."},"109":{"body":"Example, how to generate an RSA private key, key.pem - private key. public.pem - public openssl genrsa -out key.pem 2048\nopenssl rsa -in key.pem -outform PEM -pubout -out public.pem Example, how to generate an ES256 (elliptic curve) key pairs. openssl ecparam -name prime256v1 -genkey -noout -out key.pem\nopenssl ec -in key.pem -pubout -out public.pem","breadcrumbs":"User Authentication » JWT Configuration » Generating keys using OpenSSL","id":"109","title":"Generating keys using OpenSSL"},"11":{"body":"The typical example docker-compose.yml version: '3.6' services: packeton: image: packeton/packeton:latest container_name: packeton hostname: packeton environment: ADMIN_USER: admin ADMIN_PASSWORD: 123456 ADMIN_EMAIL: admin@example.com DATABASE_URL: mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4 ports: - '127.0.0.1:8080:80' volumes: - .docker:/data By default, the container starts the supervisor, which is used to run other tasks: nginx, redis, php-fpm, cron, however, you can start one service per container. See docker-compose-prod.yml example: version: '3.9' x-volumes: &default-volume volumes: - app-data:/data - app-var:/var/www/packagist/var x-restart-policy: &restart_policy restart: unless-stopped x-environment: &default-environment REDIS_URL: redis://redis DATABASE_URL: \"postgresql://packeton:pack123@postgres:5432/packeton?serverVersion=14&charset=utf8\" SKIP_INIT: 1 services: redis: image: redis:7-alpine hostname: redis <<: *restart_policy volumes: - redis-data:/data postgres: image: postgres:14-alpine hostname: postgres <<: *restart_policy volumes: - postgres-data:/var/lib/postgresql/data environment: POSTGRES_USER: packeton POSTGRES_PASSWORD: pack123 POSTGRES_DB: packeton php-fpm: image: packeton/packeton:latest hostname: php-fpm command: ['php-fpm', '-F'] <<: *restart_policy <<: *default-volume environment: <<: *default-environment SKIP_INIT: 0 WAIT_FOR_HOST: 'postgres:5432' depends_on: - \"postgres\" - \"redis\" nginx: image: packeton/packeton:latest hostname: nginx ports: - '127.0.0.1:8088:80' <<: *restart_policy <<: *default-volume command: > bash -c 'sed s/_PHP_FPM_HOST_/php-fpm:9000/g < docker/nginx/nginx-tpl.conf > /etc/nginx/nginx.conf && nginx' environment: <<: *default-environment WAIT_FOR_HOST: 'php-fpm:9000' depends_on: - \"php-fpm\" worker: image: packeton/packeton:latest hostname: packeton-worker command: ['bin/console', 'packagist:run-workers', '-v'] user: www-data <<: *restart_policy <<: *default-volume environment: <<: *default-environment WAIT_FOR_HOST: 'php-fpm:9000' depends_on: - \"php-fpm\" cron: image: packeton/packeton:latest hostname: packeton-cron command: ['bin/console', 'okvpn:cron', '--demand', '--time-limit=3600'] user: www-data <<: *restart_policy <<: *default-volume environment: <<: *default-environment WAIT_FOR_HOST: 'php-fpm:9000' depends_on: - \"php-fpm\" volumes: redis-data: postgres-data: app-data: app-var:","breadcrumbs":"Using docker » User docker compose","id":"11","title":"User docker compose"},"110":{"body":"You can run command packagist:user:manager to show the api token: bin/console packagist:user:manager admin --show-token --token-format=jwt Or you can found api token on your profile page. Keys","breadcrumbs":"User Authentication » JWT Configuration » Obtain the token","id":"110","title":"Obtain the token"},"111":{"body":"Simply use the JWT, like standard API token for composer api. Cache LDAP user loading. Since 2.0 composer downloads all packages in parallel, it may run more 12 request at the same time. To prevent calls external LDAP provider each time for JWT token verify, the obtained LDAP user object placed to cache with 60 sec TTL.","breadcrumbs":"User Authentication » JWT Configuration » Use the token","id":"111","title":"Use the token"},"112":{"body":"You can enable LDAP authenticating only on configuration level. Packeton has pre-installed Symfony LDAP component. Add the file config/packages/ldap.yaml to enable LDAP with following content. See LDAP in Symfony Docs parameters: default_login_provider: 'form_login_ldap' default_login_options: provider: all_users login_path: /login use_forward: false check_path: /login failure_path: null service: Symfony\\Component\\Ldap\\Ldap dn_string: 'uid={username},dc=example,dc=com' services: Symfony\\Component\\Ldap\\Ldap: arguments: ['@Symfony\\Component\\Ldap\\Adapter\\ExtLdap\\Adapter'] tags: - ldap Symfony\\Component\\Ldap\\Adapter\\ExtLdap\\Adapter: arguments: - host: ldap.forumsys.com port: 389 security: providers: users_ldap: ldap: service: Symfony\\Component\\Ldap\\Ldap base_dn: dc=example,dc=com search_dn: \"cn=read-only-admin,dc=example,dc=com\" search_password: password default_roles: ROLE_MAINTAINER uid_key: uid all_users: chain: providers: ['packagist', 'users_ldap'] Here is working example where used test ldap.forumsys.com server https://www.forumsys.com/2022/05/10/online-ldap-test-server/ Using LDAP integration does not prevent you from creating user manually from CLI and assign more accessible roles. At the same LDAP password validation will be done on LDAP server side, because CheckLdapCredentialsListener has higher priority loading than default check listener. Therefore, if user is not enable in LDAP - it will not able login to packeton.","breadcrumbs":"User Authentication » LDAP Configuration » Authenticating against an LDAP server","id":"112","title":"Authenticating against an LDAP server"},"113":{"body":"Packeton use Symfony Chain User Provider to lookup users. If you want to use customer user restriction by vendors and versions, packagist user provider must load before ldap. security: providers: users_ldap: ldap: ... all_users: chain: providers: ['packagist', 'users_ldap'] # Load user/roles form default packagist and if not found - use ldap user providers: ['users_ldap', 'packagist'] # packagist users will be ignore","breadcrumbs":"User Authentication » LDAP Configuration » User providers priority.","id":"113","title":"User providers priority."},"114":{"body":"You can use more 1 user providers: security: providers: users_ldap: ldap: service: Symfony\\Component\\Ldap\\Ldap base_dn: dc=example,dc=com search_dn: \"cn=read-only-admin,dc=example,dc=com\" filter: \"(&(objectclass=groupOfUniqueNames)(ou=scientists)(uniqueMember=uid={username},dc=example,dc=com))\" search_password: password default_roles: ROLE_MAINTAINER uid_key: uid users_ldap_admin: ldap: service: Symfony\\Component\\Ldap\\Ldap base_dn: dc=example,dc=com search_dn: \"cn=read-only-admin,dc=example,dc=com\" filter: \"(&(objectclass=groupOfUniqueNames)(ou=mathematicians)(uniqueMember=uid={username},dc=example,dc=com))\" search_password: password default_roles: ROLE_ADMIN uid_key: uid all_users: chain: providers: ['packagist', 'users_ldap', 'users_ldap_admin'] Here test example where exists two Groups (ou) that include: ou=mathematicians,dc=example,dc=com - assign role ROLE_ADMIN ou=scientists,dc=example,dc=com - assign role ROLE_MAINTAINER","breadcrumbs":"User Authentication » LDAP Configuration » Load different roles from LDAP.","id":"114","title":"Load different roles from LDAP."},"115":{"body":"By default, packeton is storage api token in database for each user. But if the user was loaded by custom external users' provider, but from the database, you will need enable JWT configuration. See JWT Configuration","breadcrumbs":"User Authentication » LDAP Configuration » API authentication with LDAP users.","id":"115","title":"API authentication with LDAP users."},"116":{"body":"You can use docker volume to share own configuration to application. ... volumes: - .docker:/data - ${PWD}/ldap.yaml:/var/www/packagist/config/packages/ldap.yaml","breadcrumbs":"User Authentication » LDAP Configuration » Enable LDAP for docker runtime.","id":"116","title":"Enable LDAP for docker runtime."},"117":{"body":"By default, Packeton stores packages archives on the local filesystem. But you can easily configure the S3 using league/flysystem-bundle. For docker env, please set env vars. STORAGE_SOURCE=s3\nSTORAGE_AWS_BUCKET=packeton-bucket\nSTORAGE_AWS_PREFIX=packeton\nSTORAGE_AWS_ARTIFACT_PREFIX=artifact STORAGE_AWS_ARGS='{\"endpoint\": \"https://s3.waw.io.cloud.ovh.net\", \"accessKeyId\": \"xxx\", \"accessKeySecret\": \"xxx\", \"region\": \"waw\"}' Sometimes for Artifact Repository requires direct access to files from the archive, so to improve performance and reduces count of S3 API requests, the all archives are cached on the local filesystem too. If you need to use the other provider, like Google Cloud, you may add config file to config/packages or use config.yaml in data docker dir. flysystem: storages: s3_v2.storage: adapter: 'asyncaws' options: client: 'packeton.s3.storage' bucket: '%env(STORAGE_AWS_BUCKET)%' prefix: '%env(STORAGE_AWS_PREFIX)%' s3_v2.artifact: adapter: 'asyncaws' options: client: 'packeton.s3.storage' bucket: '%env(STORAGE_AWS_BUCKET)%' prefix: '%env(STORAGE_AWS_ARTIFACT_PREFIX)%' gcloud.storage: adapter: 'gcloud' options: client: 'gcloud_client_service' bucket: 'bucket_name' prefix: 'optional/path/prefix' gcloud.artifact: adapter: 'gcloud' options: client: 'gcloud_client_service' bucket: 'bucket_name' prefix: 'optional/path/artifact' parameters: env(STORAGE_AWS_BUCKET): 'packeton-bucket' env(STORAGE_AWS_PREFIX): 'packeton' env(STORAGE_AWS_ARGS): '[]' env(STORAGE_AWS_ARTIFACT_PREFIX): 'artifact' services: packeton.s3.storage: class: AsyncAws\\S3\\S3Client arguments: $configuration: '%env(json:STORAGE_AWS_ARGS)%' $httpClient: '@Symfony\\Contracts\\HttpClient\\HttpClientInterface' $logger: '@logger' gcloud_client_service: class: Google\\Cloud\\Storage\\StorageClient arguments: - { keyFilePath: 'path/to/keyfile.json' } STORAGE_SOURCE=s3_v2\nSTORAGE_SOURCE=gcloud","breadcrumbs":"S3 Storage Provider » S3 Storage Provider","id":"117","title":"S3 Storage Provider"},"118":{"body":"If you are distributing packages to your customers, you may want to create a separate domain for Composer metadata-only to hide the default web interface and login page. Add following lines to you configuration. config.yaml or config/packages/*.yaml packeton: web_protection: ## Multi host protection, disable web-ui if host !== app.example.com and ips != 127.0.0.1, 10.9.1.0/24 ## But the repo metadata will be available for all hosts and ips. repo_hosts: ['*', '!app.example.com'] allow_ips: '127.0.0.1, 10.9.1.0/24' status_code: 402 custom_page: > # Custom landing non-auth page. Path or HTML 402 Payment Required 402 Payment Required
nginx Where custom_page html content or path to html page. Here all hosts will be hidden under this page (if ip is not match or host != app.example.com). app.example.com - this is host for default Web-UI.","breadcrumbs":"Custom landing page » Custom landing page","id":"118","title":"Custom landing page"},"119":{"body":"web_protection: repo_hosts: ['repo.example.com'] Here Web-UI will be hidden for repo_hosts host repo.example.com.","breadcrumbs":"Custom landing page » Example 2","id":"119","title":"Example 2"},"12":{"body":"Clone repository git clone https://github.com/vtsykun/packeton.git /var/www/packeton/\ncd /var/www/packeton/ Run docker-compose build docker-compose build # start container.\ndocker-compose up -d # Run with single supervisor container docker-compose up -f docker-compose-prod.yml -d # Or split","breadcrumbs":"Using docker » Build and run docker container with docker-compose","id":"12","title":"Build and run docker container with docker-compose"},"120":{"body":"Security Monitoring allow to send notifications when found a security problem in your composer.lock. By default, used packagist.org database. Packeton is automatically check the main branch of every repository if the composer.lock is exists. You need to configure notifications webhook to receive notification if found a new security issue. Also, you may see list of security advisories in the package page. logo","breadcrumbs":"Security Monitoring » Security Monitoring","id":"120","title":"Security Monitoring"},"121":{"body":"Go to Webhook page and click the \"Add Webhook\". Please fill the form. Form Description Name Any name Url Target url address. For example https://api.telegram.org/bot${secrets.TOKEN}/sendMessage Method POST Request options Symfony HTTP client options (like custom headers, auth) JSON Payload Twig render payload For example request payload for telegram. It will send JSON request, because response is array {% set text = \"New security issue *#{package.name}*\\n\\n\" %}\n{% for advisory in advisories %} {% set text = text ~ \"#{advisory.title}\\nPackage: *#{advisory.packageName}* #{advisory.version}\\n\" %} {% set text = text ~ (advisory.cve and advisory.link ? \"[#{advisory.cve}](#{advisory.link})\\n\" : \"Advisory: #{advisory.advisoryId}\\n\") %} {% set text = text ~ \"Reported at: #{advisory.reportedAt}\\n\\n\" %}\n{% endfor %} {% set response = { 'chat_id': '${secrets.CHART_ID}', 'text': text, 'parse_mode': 'Markdown'\n} %} {% return response %} Twig vars: advisories - list of advisories Composer\\Advisory\\SecurityAdvisory package - package object. Where ${secrets.CHART_ID} ${secrets.TOKEN} replace with secrets or hardcode this params. See webhooks docs.","breadcrumbs":"Security Monitoring » Configure Webhook Notifications","id":"121","title":"Configure Webhook Notifications"},"122":{"body":"Packeton import provide interface to fast mass import all private packages from your own composer repository, like Satis/Packagist. also you may use oauth2 integration to import all packages from your VCS hosting import Where Glob package filter - List of Glob to filter by package vendor name. Example input value: okvpn/*\norg1/* Select only packages (default all packages in the repository) - used if composer repository does not provide API to fetch list of all packages. Put your composer.json, composer.lock, composer info output or packages names separated by spaces or line break Example input value: sebastian/cli-parser 2.0.0 Library for parsing CLI options\nsebastian/code-unit 2.0.0 Collection of value objects that represent the PHP code units\nsebastian/code-unit-reverse-lookup 3.0.0 Looks up which function or method a line of code belongs to\nsebastian/comparator 5.0.1 Provides the functionality to compare PHP values for equality\nsebastian/complexity 3.0.1 Library for calculating the complexity of PHP code units\nsebastian/diff 5.0.3 Diff implementation\nsebastian/environment 6.0.1 Provides functionality to handle HHVM/PHP environments\nsebastian/exporter 5.0.0 Provides the functionality to export PHP variables for visualization\nsebastian/global-state 6.0.1 Snapshotting of global state\nsebastian/lines-of-code 2.0.1 Library for counting the lines of code in PHP source code Clone preference - used to select URL format. SSH or HTTPs clone.","breadcrumbs":"Migrate from Satis » Migrate from Packagist.com / Satis","id":"122","title":"Migrate from Packagist.com / Satis"},"123":{"body":"","breadcrumbs":"OAuth2 Integrations » OAuth2 and Sync integrations","id":"123","title":"OAuth2 and Sync integrations"},"124":{"body":"Pull Request review Login Restriction GitHub Setup GitHub App Setup GitLab Setup Gitea Setup Bitbucket Setup","breadcrumbs":"OAuth2 Integrations » Table of content","id":"124","title":"Table of content"},"125":{"body":"To enable OAuth2 integrations you need to add following configuration packeton: integrations: github: # Alias name allow_login: true # default false allow_register: false # default false default_roles: ['ROLE_USER', 'ROLE_MAINTAINER', 'ROLE_GITLAB'] clone_preference: 'api' repos_synchronization: true disable_hook_repos: false # disabled auto setup webhook disable_hook_org: false svg_logo: ~ #