Add GitHub Login to Datasette
Secure a local Datasette site with GitHub login and persistent sessions.
Introduction
30 Second Summary
A database can hold information you need without being suitable for everyone on the internet. Putting it in a browser creates a useful view, but it also creates a door that needs a lock.
In this project, you will publish a CSV as a browsable Datasette site protected by GitHub OAuth. You will inspect its session cookie to prove your login survives a browser restart.
What You'll Build
You will reopen your browser to a private Datasette table that still recognises your GitHub account.
By the end of this project, you'll have:
- A browsable data site that turns your CSV into a local SQLite table where you can inspect every row.
- A working GitHub login that sends you through the approval screen before returning you to the site with your username displayed.
- Proven access protection that blocks signed-out visitors in a private window while keeping your normal browser session active after a restart.
- An optional Secret Mission to push your skills further.
Are there any prerequisites?
You need Python with pip, a CSV or SQLite file, and a GitHub account that can register an OAuth app. No previous Datasette experience is required.
Before We Start
Before the hands-on work begins, lock in what you are building and why it matters. You are creating a browsable data site that uses GitHub login to keep its contents private.
Install Datasette and Load Your Data
Before you add authentication, you need proof that your data loads correctly on its own. This baseline separates data problems from login problems later.
In this step, you'll install Datasette plus sqlite-utils. You'll turn a CSV into a SQLite database that opens as a table in your browser.
In this step, get ready to:
- Install the local data toolset.
- Import data.csv into data.db.
- Run Datasette to browse the imported rows.
Install Datasette and its importer
Datasette turns SQLite databases into browsable websites. The sqlite-utils command-line tool prepares your CSV as the database that Datasette serves.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal on macOS or PowerShell on Windows.
- Press Enter to open the terminal.
- Install both local data tools by running these commands:
pip install datasette
pip install sqlite-utils
What do these commands install?
- The first pip command installs the web interface that serves your database.
- The second pip command installs the CSV importer that creates your database.
- Confirm Datasette is available in this terminal by running:
datasette --version
What does this check prove?
The command asks the active Datasette installation for its version. A version number confirms the terminal can find the installation.
You'll see a Datasette version number in the terminal.
Datasette command missing?
- Check that the installation completed without an error.
- Confirm that pip belongs to the Python environment active in this terminal.
Help me troubleshoot my Datasette installation.
Prepare and import your CSV
Datasette reads SQLite databases instead of CSV files directly. sqlite-utils copies your CSV rows into a table while retaining the original source file.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Finder on macOS or File Explorer on Windows.
- Press Enter to open the file manager.
- Locate the CSV file you want to browse.
- Copy that CSV file to your Desktop.
- Rename the Desktop copy to data.csv.
- Switch back to the terminal from earlier.
- Move the terminal to your Desktop by running this command:
cd ~/Desktop
What does this command do?
This makes your Desktop the terminal's current location. The importer can now find data.csv by its filename.
- Create data.db from your CSV by running this command:
sqlite-utils insert data.db data data.csv --csv
What does this import do?
- sqlite-utils reads the column headings plus rows from data.csv.
- The command creates data.db as the SQLite database file.
- The name data becomes the table that holds the imported rows.
- Before you check, predict whether the new database reports a table called data.
- Reveal the imported table count by running this command:
sqlite-utils tables data.db --counts
What does this check show?
The command lists every table in data.db with its row count. It checks the database without starting the website.
You'll see data with a row count greater than zero.
CSV import failing?
- Confirm the Desktop copy is named exactly data.csv.
- Check that the first row of the CSV contains column headings.
- Confirm the terminal is still using your Desktop as its current location.
Help me fix my CSV import.
Run the local site
Your database now has a real table to serve. Opening it without a login creates the baseline you will secure in later steps.
- Before you start the server, predict what the browser should list from data.db.
- Start the local server by running this command:
datasette data.db -o
What does this command do?
- Datasette serves data.db through a local web interface.
- The -o option opens that interface in your browser.
- The server keeps this terminal busy while it runs. Press Ctrl+C later when you need to stop it.
Your browser opens the Datasette interface at http://localhost:8001/.
- Select the data database from the database list.
- Select the data table from the table list.
You'll see the column headings plus rows imported from your CSV. The table opens directly because authentication has not been enabled.
That first baseline is working: your original CSV is now a browsable local data site.
Local site not opening?
- Confirm the terminal running Datasette remains open.
- Visit http://localhost:8001/ manually if the browser did not open.
- Check that data.db appears in the command you started.
Help me open my local Datasette site.
✔️ Awesome, I've got everything!
Great. Your CSV now has a browsable database behind it.
The local Datasette site is running without authentication.
ⓧ I'd like to double check the full code
Compare your finished setup with these target artifacts.
- Datasette server: Running locally without authentication, serving data.db and its imported table in the browser.
- data.csv: The learner's original CSV data file, retained as the source data loaded into SQLite.
- data.db: SQLite database created from data.csv, containing the imported browsable table.
Your local data site is ready. Next, you'll register a GitHub OAuth app for the login round trip.
Register Your GitHub OAuth App
Your table is already live in Datasette. Now it needs an identity provider before access can be tied to a GitHub account.
An OAuth app gives Datasette credentials for GitHub. Its callback URL tells GitHub exactly where to return someone after sign-in.
In this step, get ready to:
- Register a GitHub OAuth App for your local Datasette site.
- Generate the OAuth client credentials.
- Save the credentials in a local metadata.json file.
Register the OAuth app
GitHub uses the registered callback URL as an approved return address. A mismatch prevents the sign-in round trip from reaching your local Datasette site.
- Switch back to the browser from earlier.
- Open the GitHub OAuth App registration page in a new tab.
- Complete any identity check that GitHub displays.
- Enter Local Datasette Data in the Application name field.
- Enter http://127.0.0.1:8001/ in the Homepage URL field.
- Enter http://127.0.0.1:8001/-/github-auth-callback in the Authorization callback URL field.
- Leave the optional description empty.
- Click Register application.
That registration is the bridge between GitHub and your local site. You should now see the OAuth app settings page with a client ID.
Why Must the Callback URL Match?
GitHub sends the browser to this address after the account owner approves the app. The exact scheme, host, port, and path identify the destination.
The plugin listens at http://127.0.0.1:8001/-/github-auth-callback. That exact match keeps the sign-in flow connected to your Datasette server.
Store the OAuth credentials locally
The next screen deals with a client secret, which deserves the same care as a password. This project stores it only in a local configuration file.
- Keep the Client ID visible on the OAuth app settings page.
- Click Generate a new client secret.
- Complete the identity check that GitHub displays.
- Copy the newly generated client secret immediately.
Keep the Client Secret Local
The client secret allows software to identify itself as your OAuth app. Anyone with access to the secret could impersonate that app.
Keep metadata.json on your laptop. Never commit it to version control or include it in a screenshot.
- Choose your operating system below to open a plain-text editor:
macOS
- Press Cmd+Space to open Spotlight.
- Type TextEdit and press Enter.
- Create a new document from the File menu.
- Click Format in the menu bar.
- Click Make Plain Text.
Windows
- Press the Windows key to open search.
- Type Notepad and press Enter.
- Create a new document from the File menu.
- Build metadata.json by copying this template into the editor:
{"plugins":{"datasette-auth-github":{"client_id":"<GitHub OAuth client ID>","client_secret":"<GitHub OAuth client secret>"}}}
What Does This Configuration Do?
- The plugins object holds settings for Datasette plugins.
- The datasette-auth-github object identifies the authentication plugin used by this project.
- The client_id value identifies your registered OAuth app.
- The client_secret value proves that Datasette has the app's private credential.
- Replace <GitHub OAuth client ID> with the client ID from the GitHub settings page.
- Replace <GitHub OAuth client secret> with the client secret you copied.
- Press Cmd+S on macOS or Ctrl+S on Windows.
- Enter metadata.json as the file name.
- Select the folder that already contains data.db.
- Click Save.
Good progress. Your OAuth app credentials now have a local configuration file ready for Datasette.
Metadata File Looks Wrong?
Check that the file is named metadata.json. Rename it if your editor added a .txt extension.
Make sure both credential values remain inside double quotes. Keep every brace from the template.
Help me fix my metadata configuration.
✔️ Awesome, I've got everything!
Great. Double check that metadata.json is saved beside data.db with your real OAuth credentials.
ⓧ I'd like to double check the full code
The structure should match this file exactly. Your saved file should contain the real credential values in place of the two placeholders.
{"plugins":{"datasette-auth-github":{"client_id":"<GitHub OAuth client ID>","client_secret":"<GitHub OAuth client secret>"}}}
How to Compare Safely
Compare the keys, braces, and quotation marks against the reference. Keep your real client secret inside your local file only.
Verify the registered app
Before you check, do you expect GitHub to show the callback URL exactly as you entered it?
- Return to the OAuth app settings tab.
- Confirm the Application name displays Local Datasette Data.
- Confirm the Homepage URL displays http://127.0.0.1:8001/.
- Confirm the Authorization callback URL displays http://127.0.0.1:8001/-/github-auth-callback.
- Confirm a Client ID is present.
- Confirm the generated client secret is listed with its value concealed.
You should see the local homepage, the exact callback URL, a client ID, and a concealed client secret. That confirms the OAuth app is registered without exposing its private credential.
Your GitHub OAuth App is registered, and its credentials are stored locally. Next up, you will install the authentication plugin and connect it to this configuration.
Enable GitHub Authentication
Your GitHub OAuth app is registered. Its credentials are safely stored in metadata.json on your laptop.
Your next goal is to make GitHub login appear inside Datasette. The datasette-auth-github plugin creates the connection between your local site and GitHub.
The running server started before that plugin existed. Restarting it with metadata.json loads the authentication settings.
In this step, get ready to:
- Install the datasette-auth-github plugin in the active Python environment.
- Restart Datasette with data.db and metadata.json.
- Confirm the Datasette menu shows a GitHub login link.
Install the authentication plugin
A Datasette plugin adds features to the server without changing data.db. This plugin adds the GitHub login flow that uses your existing OAuth app.
- Switch back to the terminal running Datasette.
- Stop the current server by pressing Ctrl+C.
- Install the authentication plugin by running this command:
datasette install datasette-auth-github
What does this command do?
- The datasette installer places the plugin in the same Python environment as Datasette.
- The datasette-auth-github plugin provides the GitHub authentication flow.
- The installation leaves your existing database and configuration file unchanged.
That is the authentication bridge installed. Your Datasette environment can now load GitHub login support.
Installation failing?
- Confirm the active Python environment is the one where you installed Datasette.
- Check that your laptop has an internet connection so the package can download.
Still stuck? Help me troubleshoot the plugin installation.
Restart Datasette with its configuration
Datasette discovers the installed authentication plugin when the server starts. The start command also points the server at the configuration containing your OAuth credentials.
Keep the client secret off-screen
This check only needs the table page and its menu. Your evidence can stay clear of metadata.json.
Datasette keeps this terminal occupied while the local server runs. The browser becomes your checkpoint while the process remains active.
- Restart Datasette with the database and configuration by running this command:
datasette data.db -m metadata.json
How does this start authentication?
- The data.db argument serves the database you loaded earlier.
- The -m option loads the settings from metadata.json.
- The installed plugin reads those settings when Datasette starts.
- Keep the terminal running while you complete the browser check.
- Confirm the terminal shows that the local Datasette server has started.
The server is back with its authentication settings loaded. It is ready to expose the login flow in the browser.
Server not starting?
- Confirm data.db is in the current terminal folder.
- Confirm metadata.json is in the same folder.
- Check the JSON structure for missing braces or quotation marks without sharing the client secret.
Need another pair of eyes? Help me diagnose the Datasette startup problem.
Confirm the GitHub login link
Before you refresh, which new menu action do you expect the restarted plugin to add?
- Switch back to the table page from earlier.
- Refresh the table page.
- Open the Datasette menu.
You should see a GitHub login link in the menu. This proves the plugin loaded your local authentication settings.
Login link missing?
- Confirm the Datasette process is still running in the terminal.
- Confirm the startup command loaded metadata.json.
- Refresh the table page after the restarted server finishes loading.
Still missing the link? Help me find why GitHub login is not appearing.
Your local data site now offers GitHub login. Next, you will complete the OAuth round trip and return as a signed-in actor.
Sign In with GitHub
Your Datasette site now shows a GitHub login link. The next test proves that the link can identify you.
This step sends you through an OAuth redirect round trip. GitHub asks you to approve the OAuth App.
The redirect must return to the same local Datasette site. Your GitHub username is the proof that the full sign-in flow worked.
In this step, get ready to:
- Follow the login redirect from Datasette to GitHub.
- Approve your registered GitHub OAuth App.
- Confirm your GitHub identity in Datasette.
Start the GitHub sign-in flow
What happens during the redirect?
Datasette sends your browser to GitHub. GitHub can then identify the account approving the request.
After approval, GitHub sends your browser back to your local Datasette site through the callback URL.
- Click the Datasette menu on the table page from earlier.
- Select the GitHub login link.
Your browser takes you to GitHub. You should see the approval page for your OAuth App.
GitHub page did not open?
- Refresh the table page if the Datasette menu did not respond.
- Confirm the Datasette server from earlier is still running if the local page does not load.
If the approval page still does not open, help me troubleshoot the GitHub login redirect.
Approve your OAuth App
Approving a login connection can feel sensitive. The GitHub page lets you review the OAuth App before continuing.
- Sign in to GitHub if GitHub asks you to authenticate.
- Confirm the approval page names the OAuth App you registered.
- Approve the OAuth App using the authorization button on the GitHub page.
GitHub completes the redirect. You should return to your local Datasette site.
Did not return to Datasette?
- Compare the local address in your browser with the callback URL registered for the OAuth App.
- Update the callback URL in GitHub developer settings if the addresses differ.
- Repeat the login flow after saving the corrected callback URL.
If the redirect still fails, help me diagnose the callback URL.
Confirm your GitHub identity
Datasette represents a signed-in identity as an actor. The menu displays the GitHub username attached to that actor.
Before you check, which GitHub username do you expect Datasette to show?
- Click the Datasette menu to reveal the current signed-in identity.
You should see your own GitHub username in the Datasette menu. That's the full redirect round trip working: Datasette now recognizes your GitHub identity.
Username missing?
- Refresh the local Datasette page once.
- Repeat the GitHub login flow if the menu still shows the login link.
If your username still does not appear, help me troubleshoot my Datasette sign-in.
Your GitHub identity is now connected to your local Datasette site. Next, you'll inspect the session cookie to learn when this login expires.
Inspect the Session Cookie
Your GitHub login now returns you to Datasette as an authenticated user. That visible username proves the OAuth round trip works.
The browser now holds a session cookie from datasette-auth-github. Its lifetime fields decide whether your login survives a full browser restart.
In this step, get ready to:
- Open developer tools for the local Datasette site.
- Find the ds_actor authentication cookie.
- Record the cookie lifetime without exposing its value.
Open developer tools
Browser developer tools expose storage attached to the current site. Keep the tools open after you reach the cookie table.
Chrome
- Return to the local Datasette page in your signed-in browser tab.
- Right-click an empty area of the page.
- Select Inspect.
- Select Application in developer tools.
- Expand Storage in the left sidebar.
- Expand Cookies.
- Select the local Datasette origin.
You will see a cookie table for the local Datasette site.
Firefox
- Return to the local Datasette page in your signed-in browser tab.
- Open Firefox's main menu.
- Select Browser Tools.
- Select Web Developer Tools.
- Select Storage in developer tools.
- Expand Cookies.
- Select the local Datasette origin.
You will see the cookies stored for the local Datasette site.
Safari
- Return to the local Datasette page in your signed-in browser tab.
- Select Develop in the macOS menu bar.
- Select Show Web Inspector.
- Select Storage.
- Select Cookies for the current site.
You will see the cookies stored by the local Datasette page.
Can't find the storage view?
- Widen the developer tools pane if its storage tab is hidden.
- Confirm developer tools are inspecting the signed-in Datasette tab.
- Enable Safari's developer features in its advanced settings if the Develop menu is missing.
Help me find my browser's cookie storage view.
Locate the authentication cookie
Datasette reads the signed ds_actor cookie to identify the current user. Its Value cell can carry your live login credential.
Cookie tables are a little sensitive because a screenshot can capture the full value. A brief privacy check here protects your active session.
- Find the row named ds_actor in the Name column.
- Select the ds_actor row.
- Keep the Value cell hidden from anyone nearby.
- Confirm the Name column still shows ds_actor.
The selected row exposes the attributes that control the authentication cookie's lifetime.
What does ds_actor store?
The ds_actor cookie contains a signed actor record. Datasette uses that record to restore your authenticated identity on later requests.
The signature protects the record from undetected changes. The cookie value still grants access as your signed-in actor.
Can't see ds_actor?
- Reload the local Datasette page.
- Confirm the Datasette menu still shows your GitHub username.
- Select the exact local origin used by the signed-in page.
Help me locate the Datasette authentication cookie.
Record the cookie lifetime
Max-Age expresses a cookie lifetime as a number of seconds. Expires expresses the same deadline as a calendar timestamp.
Your browser may combine both signals under Expires / Max-Age. Safari can show the calendar timestamp under Expires.
Before you inspect the lifetime, do you expect a browser-session-only value or a future expiry?
- Read the lifetime field for the ds_actor row.
- Record the displayed Max-Age or combined lifetime value here: your displayed Max-Age value.
- Record the displayed Expires timestamp here: your displayed Expires value.
- Keep developer tools open with the ds_actor row selected.
You found the evidence. The ds_actor row has a future expiration that can survive a browser restart.
Why does the expiry matter?
datasette-auth-github version 1.0 sets the cookie for login_max_age seconds. The default lifetime is 30 days.
A future expiry makes the cookie persistent across browser sessions. The next test checks that behavior directly.
Seeing Session instead?
- Confirm you selected the ds_actor row.
- Revisit the plugin installation from earlier if the lifetime field still shows Session.
- Confirm datasette-auth-github is version 1.0 or newer.
Help me diagnose a session-only Datasette cookie.
- Cover the cookie's Value cell with a solid redaction before capturing your screenshot.
- Frame the screenshot around the cookie name plus its lifetime fields.
Your session lifetime is now recorded. Next, you'll test signed-out access before proving the login survives a browser restart.
Restrict Access and Verify Persistence
Your local Datasette site already recognizes your GitHub identity. You have also recorded the lifetime of its session cookie.
The table remains public until Datasette checks that identity against a permission rule. You will close that gap for signed-out visitors.
Then you will test whether the recorded cookie expiry keeps your normal browser signed in after a full restart.
In this step, get ready to:
- Add an instance-level permission for your GitHub username.
- Restart Datasette with the restricted metadata.
- Compare signed-out access with persistent signed-in access.
Restrict the instance to your GitHub identity
Your existing plugins object handles sign-in. A root-level permissions object decides which signed-in actor can view the site.
Protect your client secret
This sensitive file deserves a careful edit because only the permission section should change. The existing client secret stays unchanged.
- Keep the actual client_id value already stored in metadata.json.
- Keep the actual client_secret value already stored in metadata.json.
- Avoid copying either credential into a screenshot or message.
- Switch back to metadata.json in the editor from earlier.
- Find the final three closing braces shown below:
}}}
What do these braces close?
- The first brace closes the GitHub plugin settings.
- The second brace closes the plugins object.
- The third brace closes the outer JSON object.
- Replace those final three braces with the structure below:
}},"permissions":{"view-instance":{"id":"<learner GitHub username>"}}}
How does the permission work?
- The comma places permissions beside plugins in the outer JSON object.
- The view-instance permission controls who can view this Datasette instance.
- The id value must match your signed-in GitHub username.
- Replace <learner GitHub username> with the exact username shown in your signed-in Datasette menu.
- Save metadata.json.
- Confirm that permissions sits beside plugins in the outer JSON object.
✔️ Awesome, I've got everything!
Great. Double check that metadata.json is saved with your real GitHub username in the permission rule.
ⓧ I'd like to double check the full code
Compare your file with this structure. Keep the real client ID and client secret already stored in your file.
{"plugins":{"datasette-auth-github":{"client_id":"<GitHub OAuth client ID>","client_secret":"<GitHub OAuth client secret>"}},"permissions":{"view-instance":{"id":"<learner GitHub username>"}}}
Restart Datasette and test signed-out access
A permission change takes effect when Datasette reads metadata.json during startup. Restarting applies the new access rule to every request.
- Return to the terminal running Datasette from earlier.
- Stop the running server by pressing Ctrl+C.
- Restart the restricted instance by running this command:
datasette data.db --metadata metadata.json
What does this command do?
- The datasette command starts the local server.
- The data.db argument loads your imported table.
- The --metadata option tells Datasette to read metadata.json.
- The terminal stays occupied while the local server is running.
- Leave this terminal running while you test the site.
- Switch back to the normal browser window from earlier.
- Refresh the protected table page.
You will see the table rows with your GitHub username still shown in the Datasette menu. Your signed-in session now passes the new permission check.
Server failing or normal access blocked?
A JSON parsing error usually means the replacement has an extra brace or a missing comma. Compare the end of metadata.json with the full-code tab.
A permission denied page in your normal browser usually means the id value does not exactly match your GitHub username. Check its spelling and capitalization.
If the old access behavior remains after a successful restart, confirm the command loaded the same metadata.json file you edited.
Help me troubleshoot my restricted Datasette configuration.
- Click the address bar in your normal browser.
- Copy the full protected table URL.
- Record it here: your local Datasette table URL.
Before you load the table privately, do you expect a signed-out visitor to see the rows? Hold that prediction for the check.
- Use your browser's main menu to open a new private browsing window.
- Paste your local Datasette table URL into the address bar.
- Press Enter to load the protected table.
You will see a permission denied page instead of the table rows. This proves that signed-out visitors cannot view the instance.
Private window still showing the table?
A previously open private browsing session may still carry a GitHub login. Close every private window before opening a fresh one.
If the table remains visible while signed out, confirm that the restarted server loaded the restricted metadata.json file.
Help me diagnose why my private window can still view the protected Datasette table.
Quit and reopen your normal browser
The private-window check proves that the permission rule works. The final check tests whether your normal authentication session survives a complete browser restart.
Before you quit the browser, do you expect the recorded cookie expiry to keep you signed in? Hold that prediction while you restart it.
- Close every private browser window.
- Quit your normal browser completely with Cmd+Q on macOS or by closing every browser window on Windows.
- Press Cmd+Space on macOS or the Windows key on Windows to open the search bar.
- Type the name of your normal browser into the search bar.
- Press Enter to reopen the browser.
- Paste your local Datasette table URL into the address bar.
- Press Enter to load the protected table.
You will see the table rows without another GitHub login. Your username will still appear in the Datasette menu.
What does this prove?
The permission rule still checks your identity after the restart. Your recorded cookie expiry allows the browser to restore that authenticated identity.
The private window remains blocked because it has no copy of the normal browser's authentication cookie.
- Reopen browser developer tools using the same method from earlier.
- Return to the cookie storage view from earlier.
- Find the same Datasette authentication cookie for the local site.
You will see that the authentication cookie remains available after the browser restart. That closes the loop. Your data is protected while your approved session stays usable.
Secret mission
Prove What the Cookie Controls
Delete the local Datasette authentication cookie to prove what controls your browser session. Sign back in with GitHub to create a fresh cookie. Restart the browser once more to confirm the replacement session persists.
Clean Up Your Resources
Clean Up Your Resources
Everything in this project ran on your laptop, so there are no ongoing service costs. Choose whether to keep the setup ready, stop the local server for later, or remove the project resources.
Resources you used:
- The local Datasette server process that serves data.db with the restrictions from metadata.json.
- The source CSV file named data.csv.
- The SQLite database file named data.db.
- The local metadata.json configuration file that contains your GitHub client secret.
- The GitHub OAuth App registered under your GitHub account.
Keep everything running
No action is needed. Choose this if you plan to keep browsing the protected database or reuse the login setup.
Your metadata.json file contains the client secret. It stays protected while it remains local and outside version control.
- Leave the existing Datasette server process running while you use the site.
- Keep data.csv as the original source data.
- Keep data.db as the browsable database.
- Keep metadata.json outside version control.
- Retain the registered GitHub OAuth App for this local login setup.
Pause - I'll come back to this later
Shut down the running server to free its local port. Your files and OAuth App remain ready for another session.
- Return to the terminal that is running the local Datasette server.
- Press Ctrl+C to stop the server process.
That gives you a clean stopping point. You should see your terminal prompt again when the server has stopped.
- Keep data.csv in its current local folder.
- Keep data.db in its current local folder.
- Keep metadata.json local and outside version control.
- Keep the GitHub OAuth App registered for your next Datasette session.
Delete - I don't want to use this again
This permanently removes the local data, configuration, and registered OAuth App. The cleanup only affects resources from this project.
- Return to the terminal that is running the local Datasette server.
- Press Ctrl+C to stop the server process.
You should see your terminal prompt again. The local site is now offline.
- Return to GitHub developer settings from earlier.
- Open the OAuth App that uses your local Datasette callback URL.
- Scroll to the permanent deletion area at the bottom of the app settings.
- Choose the deletion control in that area.
- Complete the confirmation prompt.
- Return to the list of registered OAuth Apps.
You should no longer see the Datasette OAuth App in the list. Its client ID and client secret can no longer power the local login flow.
The final project-specific resources are the three local files. Use the instructions for your operating system to remove them permanently.
macOS
- Press Cmd+Space to open macOS search.
- Search for Finder.
- Open the Finder result.
- Navigate to the folder where you saved metadata.json.
- Select data.csv, data.db, and metadata.json.
- Move the selected files to the macOS trash.
- Empty the macOS trash.
- Return to the folder that held the files.
You should no longer see data.csv, data.db, or metadata.json.
Windows
- Press the Windows key to open Windows search.
- Search for File Explorer.
- Open the File Explorer result.
- Navigate to the folder where you saved metadata.json.
- Select data.csv, data.db, and metadata.json.
- Move the selected files to the Windows recycle bin.
- Empty the Windows recycle bin.
- Return to the folder that held the files.
You should no longer see data.csv, data.db, or metadata.json.
That closes the loop. Your local server, registered OAuth App, and project-specific files are gone.
Nice Work!
Nice Work!
You did it! You built a local Datasette site that protects your CSV data behind a GitHub login. You also proved that the authenticated session survives a full browser restart.
You've learned how to:
- Turned data.csv into a browsable table backed by data.db using SQLite.
- Connected GitHub OAuth to Datasette. Completed the redirect round trip to sign in as your own GitHub actor.
- Enforced access control with the view-instance permission. Proved that signed-out visitors are blocked in a private window. Confirmed that the persistent session survives reopening your normal browser.
- Completed the optional Secret Mission to push your skills further.
Ready to quiz yourself?