From d750c0ee553bf7725243f95411832c083270f891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Bara=C3=BAna?= Date: Wed, 1 Oct 2025 19:42:10 -0300 Subject: [PATCH] Docs for integration with Git --- docs/images/open-from-git.png | Bin 0 -> 39628 bytes docs/teams/git_file_storage.md | 90 +++++++++++++++++++++++++++++++++ mix.exs | 1 + 3 files changed, 91 insertions(+) create mode 100644 docs/images/open-from-git.png create mode 100644 docs/teams/git_file_storage.md diff --git a/docs/images/open-from-git.png b/docs/images/open-from-git.png new file mode 100644 index 0000000000000000000000000000000000000000..3dde3220bfb94681b733aa151c121a67e816eaf6 GIT binary patch literal 39628 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

Kcv0y{RT-@b;f;j>+_%c%)!<^Y$0mA@;t~0 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 iZ=b#cI4<2$C2VsJ_ #### Livebook version requirement {: .info} +> Requires Livebook v0.18 or newer. + + +## Add a Git file storage to your Teams workspace + +1. Open Livebook +2. Navigate to your Teams workspace page by clicking on the team name in the sidebar +3. Scroll to the "File storages" section and click **Add file storage** +4. Select **Git** as the file storage type +5. Fill in the Git repository details: + - **Repository URL**: Enter the SSH URL of your Git repository (e.g., `git@github.com:username/repo-name.git`) + - **Branch**: Specify the branch to use (e.g., `main`) + - **Private key**: Paste an SSH private key that has access to the repository (read-only access is enough) +6. Click **Add** to save the configuration + +Once configured, the Git file storage will be synced across all team members and Livebook app servers that belong to your Teams organization. + +> #### Which SSH private key should I use? {: .tip} +> Livebook connects to Git repositories over SSH, so you need to provide a private key with access to the repo. +> +> The recommended way is to create a new SSH key pair and add the public key as a deploy key for your Git repository inside your Git provider ([GitHub](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys#set-up-deploy-keys), [GitLab](https://docs.gitlab.com/user/project/deploy_keys/#create-a-project-deploy-key), [Bitbucket](https://support.atlassian.com/bitbucket-cloud/docs/set-up-repository-access-keys-on-linux/), etc.), then use the private key for the Livebook configuration. +> +> Livebook only needs **read-only access**, so when adding the deploy key to your Git repo, you can grant read-only permissions only. + +## Open a notebook from the Git repository + +After adding the Git file storage, members and app servers of your Teams organization can access notebooks stored in the repository: + +1. From the Livebook home page, click **Open** to open a notebook +2. Make sure you're in the **From storage** tab, and click on the file storage dropdown, saying "Disk" +3. Click on the Git file storage you configured (it will be listed with your repository URL) +4. Browse the repository files and click on the notebook file you want to open +5. Click **Fork** to open the notebook in a new session + +The notebook will open and be ready to use. + +It's worth noting that **Livebook treats notebooks inside a Git file storage as read-only**. That's +why you have to "fork" the notebook, which creates a copy. Any changes you make are local to your session and won't affect the original file in the Git repository. + +## Examples of when this feature is useful + +This feature is particularly useful when working inside an [app server](/teams_concepts.md#app-server) from your Teams organization and you need to open shared notebooks stored in a Git repository. + +Common use cases include: + +* **Templates and boilerplate** - Access frequently needed code inside an app server +* **Runbooks** - Open operational runbooks directly in your app server to interact with production systems + +## Examples of when this feature is not needed + +### Sharing notebooks with team members for local development + +If your team members need to edit and collaborate on notebooks in their local Livebook instances, use standard Git workflows instead: + +1. Team members clone the Git repository to their local machines +2. Open notebooks directly from the cloned repository +3. Edit, commit, and push changes using Git + +**Use Git file storage when**: You need to access the notebook from an app server, since app servers don't have direct access to your Git repository. + +### Deploying Livebook apps + +If you want to give someone access to a Livebook app (not edit the notebook): + +1. [Deploy your notebook as a Livebook app](deploy_app.md) +2. Share your app server URL with users + +This allows users to use the app without notebook editing capabilities. + +**Use Git file storage when**: Team members need to open shared notebooks as regular notebooks inside an app server, not as deployed apps. + +## Security + +Your SSH private key is encrypted end-to-end and never accessible to Livebook Teams in plaintext. + +Livebook encrypts your SSH private key locally using your Teams key before sending it to Livebook Teams servers. When a Git file storage is added or edited, team members' Livebook instances and app servers receive the encrypted key and decrypt it locally using the same Teams key. + +This ensures that only members of your Teams organization can access the private key. diff --git a/mix.exs b/mix.exs index 698dfdbb2..0331b84e9 100644 --- a/mix.exs +++ b/mix.exs @@ -267,6 +267,7 @@ defmodule Livebook.MixProject do "docs/teams/oidc_groups.md", "docs/teams/shared_secrets.md", "docs/teams/shared_file_storages.md", + {"docs/teams/git_file_storage.md", title: "Open notebooks from a private Git"}, {"docs/teams/phoenix_integration.md", title: "How-to integrate with a Phoenix app"}, {"docs/teams/teams_concepts.md", title: "Livebook Teams concepts"}, "docs/authentication/basic_auth.md",