@skillcdn/console 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,118 @@
1
+ {
2
+ "Version": "2012-10-17",
3
+ "Statement": [
4
+ {
5
+ "Sid": "WhoAmIAndPrices",
6
+ "Effect": "Allow",
7
+ "Action": ["sts:GetCallerIdentity", "pricing:GetProducts", "ec2:DescribeRegions"],
8
+ "Resource": "*"
9
+ },
10
+ {
11
+ "Sid": "Network",
12
+ "Effect": "Allow",
13
+ "Action": [
14
+ "ec2:DescribeVpcs",
15
+ "ec2:DescribeSubnets",
16
+ "ec2:DescribeSecurityGroups",
17
+ "ec2:DescribeAvailabilityZones",
18
+ "ec2:DescribeNetworkInterfaces",
19
+ "ec2:CreateDefaultVpc",
20
+ "ec2:CreateSecurityGroup",
21
+ "ec2:DeleteSecurityGroup",
22
+ "ec2:AuthorizeSecurityGroupIngress",
23
+ "ec2:RevokeSecurityGroupIngress",
24
+ "ec2:CreateTags"
25
+ ],
26
+ "Resource": "*"
27
+ },
28
+ {
29
+ "Sid": "Containers",
30
+ "Effect": "Allow",
31
+ "Action": ["ecs:*", "ecr:*", "logs:*"],
32
+ "Resource": "*"
33
+ },
34
+ {
35
+ "Sid": "Database",
36
+ "Effect": "Allow",
37
+ "Action": ["rds:*"],
38
+ "Resource": "*"
39
+ },
40
+ {
41
+ "Sid": "Files",
42
+ "Effect": "Allow",
43
+ "Action": ["s3:*"],
44
+ "Resource": ["arn:aws:s3:::console-*", "arn:aws:s3:::console-*/*"]
45
+ },
46
+ {
47
+ "Sid": "ListBuckets",
48
+ "Effect": "Allow",
49
+ "Action": ["s3:ListAllMyBuckets"],
50
+ "Resource": "*"
51
+ },
52
+ {
53
+ "Sid": "Parameters",
54
+ "Effect": "Allow",
55
+ "Action": [
56
+ "ssm:PutParameter",
57
+ "ssm:GetParameter",
58
+ "ssm:GetParameters",
59
+ "ssm:GetParametersByPath",
60
+ "ssm:DeleteParameter",
61
+ "ssm:AddTagsToResource"
62
+ ],
63
+ "Resource": "arn:aws:ssm:*:*:parameter/console/*"
64
+ },
65
+ {
66
+ "Sid": "ListParameters",
67
+ "Effect": "Allow",
68
+ "Action": ["ssm:DescribeParameters"],
69
+ "Resource": "*"
70
+ },
71
+ {
72
+ "Sid": "RolesAndUsersOfTheConsole",
73
+ "Effect": "Allow",
74
+ "Action": [
75
+ "iam:CreateRole",
76
+ "iam:DeleteRole",
77
+ "iam:GetRole",
78
+ "iam:UpdateAssumeRolePolicy",
79
+ "iam:AttachRolePolicy",
80
+ "iam:DetachRolePolicy",
81
+ "iam:PutRolePolicy",
82
+ "iam:DeleteRolePolicy",
83
+ "iam:ListAttachedRolePolicies",
84
+ "iam:ListRolePolicies",
85
+ "iam:PassRole",
86
+ "iam:TagRole",
87
+ "iam:CreateUser",
88
+ "iam:DeleteUser",
89
+ "iam:GetUser",
90
+ "iam:PutUserPolicy",
91
+ "iam:DeleteUserPolicy",
92
+ "iam:CreateAccessKey",
93
+ "iam:DeleteAccessKey",
94
+ "iam:ListAccessKeys",
95
+ "iam:TagUser"
96
+ ],
97
+ "Resource": ["arn:aws:iam::*:role/console-*", "arn:aws:iam::*:user/console-*"]
98
+ },
99
+ {
100
+ "Sid": "ServiceLinkedRolesAndTheGitHostProvider",
101
+ "Effect": "Allow",
102
+ "Action": [
103
+ "iam:CreateServiceLinkedRole",
104
+ "iam:CreateOpenIDConnectProvider",
105
+ "iam:GetOpenIDConnectProvider",
106
+ "iam:ListOpenIDConnectProviders",
107
+ "iam:TagOpenIDConnectProvider"
108
+ ],
109
+ "Resource": "*"
110
+ },
111
+ {
112
+ "Sid": "BudgetAlert",
113
+ "Effect": "Allow",
114
+ "Action": ["budgets:ViewBudget", "budgets:ModifyBudget"],
115
+ "Resource": "*"
116
+ }
117
+ ]
118
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "_": "The shape of the secrets file the run keeps outside any repository and deletes, on the person's word, once every value is in the parameter store. A value is what the run generated or derived, what the person gave, or the word later; a provider the person did not choose has no line.",
3
+ "AUTH_SECRET": "generated: 48 random characters, never shown",
4
+ "DATABASE_URL": "derived: postgres://console:<generated password>@<database endpoint>:5432/console",
5
+ "DATABASE_CA": "derived: the regional certificate bundle of the database service, as PEM",
6
+ "S3_ACCESS_KEY_ID": "derived: the access key id of the files user",
7
+ "S3_SECRET_ACCESS_KEY": "derived: its secret",
8
+ "TUNNEL_TOKEN": "derived: the connector token of the tunnel",
9
+ "GITHUB_CLIENT_SECRET": "asked: the client secret of the OAuth app, or later",
10
+ "GOOGLE_CLIENT_SECRET": "asked: the client secret of the OAuth client, or later"
11
+ }
@@ -0,0 +1,78 @@
1
+ # Access: what the person creates once, and how it reaches the agent
2
+
3
+ What the agent needs to act on the organization's accounts, the exact steps of the day for the person to create each, and how each value reaches the agent without passing through the chat. Dashboards move; every path here carries the month it was checked, and the vendor's own page is the source when a label has changed.
4
+
5
+ ## The AWS account and the deployer
6
+
7
+ **Which account.** The skill asks whether the organization has an account for this. A dedicated AWS account for the console is the simplest to run and to read the bill of: nothing else shares it, and one budget alert covers it. An account that already runs other things works with the scoped policy below. A new account (`aws.amazon.com`, Create an AWS account; a payment method is asked; checked 2026-10) is created by the person on the **paid plan**, once the order of cost is in front of them (the skill's second message): the free plan ends after six months and closes the account with its data, and a console is meant to stay. Both plans start with credits, which the paid plan spends on the first months' bills.
8
+
9
+ **The deployer user and its policy.** Signed in to the account, in the IAM console (checked 2026-10):
10
+
11
+ 1. Users, Create user. Name `console-deployer`. Leave console access off: this user is for the agent's commands only. Next.
12
+ 2. Permissions: Attach policies directly. In a dedicated account, `AdministratorAccess`, which is the honest choice when nobody else is in the account. In a shared account, first create a policy from [deployer-policy.json](../assets/deployer-policy.json) (Policies, Create policy, JSON, paste, name it `console-deployer`), then attach that one. The scoped policy is broad where names cannot be known in advance and tight where they can (`console-` prefixed roles, users and buckets, `/console/` parameters); a step the policy does not cover fails with `AccessDenied` naming the action, and the fix is to add that action.
13
+ 3. Create user. Open it, Security credentials, Access keys, Create access key. Use case: Command Line Interface (and tick the confirmation), or Other. Next, Create access key. **Download .csv file.** The secret is shown once; the file is the one copy.
14
+
15
+ **How the key reaches the agent.** Save the downloaded file as `.aws-key.csv` in the run's folder, and tell the agent. The agent reads the two values from the file with a script, writes them as the profile `console` into the AWS CLI's own credentials file (`~/.aws/credentials`, the person's file, readable by them alone where the system can say so), sets the region on the profile, and deletes `.aws-key.csv`; neither value is ever written in a command line, a message or a log. A key pasted into the chat instead is written to the profile the same way and never repeated, and the person is told to make a new key once the run is over, since the chat kept a copy.
16
+
17
+ **The AWS CLI.** Version 2: `aws --version`. Without it, Windows: `winget install Amazon.AWSCLI`; macOS: `brew install awscli`, or the installer at `docs.aws.amazon.com/cli` (checked 2026-10). The agent installs it with the person's word.
18
+
19
+ **Verify:**
20
+
21
+ ```sh
22
+ aws sts get-caller-identity --profile console # the account id, and the user's ARN
23
+ aws ec2 describe-vpcs --profile console --filters Name=is-default,Values=true --query 'Vpcs[0].VpcId'
24
+ ```
25
+
26
+ The first answers with the account id the plan names; the second with the default VPC, or nothing, in which case `aws ec2 create-default-vpc` makes one (the deployer's policy allows it). Every command of the run carries `--profile console` (or `AWS_PROFILE=console` in the shell) and `--region <region>`.
27
+
28
+ ## The Cloudflare account and the token
29
+
30
+ **The domain.** The console's address is a hostname of a zone on Cloudflare: a domain the organization already has, moved to Cloudflare's nameservers (the zone is made first in the run, and the two nameservers it answers go to the person to set at their registrar), or one bought through Cloudflare's Registrar in the run with its price shown first. There is no free hostname for a tunnel; a domain is needed. The account is free (`dash.cloudflare.com/sign-up`).
31
+
32
+ **The nameservers, at the registrar.** The person named the registrar with the domain; give its steps where they are known (the registrar's own help page for "nameservers" or "DNS settings", read at run time), and otherwise the general ones: sign in at the registrar, open the domain, find the nameserver (NS) setting, replace what is there with the two names Cloudflare gave, save; the change takes minutes to hours to reach the world, and the run checks the zone's status until it is `active`. Everything else of the domain's DNS (mail records, other hosts) is copied into the Cloudflare zone before the switch, from what the registrar shows, so that nothing stops working; the run asks for that list when the domain already serves something.
33
+
34
+ **The token.** My Profile, API Tokens (`dash.cloudflare.com/profile/api-tokens`), Create Token, **Create Custom Token** (checked 2026-10). Name it `console deploy`. Permissions, one row each:
35
+
36
+ | Scope | Permission | Level | For |
37
+ |---|---|---|---|
38
+ | Account | Cloudflare Tunnel | Edit | The tunnel the task connects out through, and its routing |
39
+ | Account | Account Settings | Read | Listing accounts, the account id |
40
+ | Zone | DNS | Edit | The console's hostname |
41
+ | Zone | Zone | Edit | Making the zone for a domain the organization owns, finding it, its status and nameservers |
42
+ | Zone | Zone Settings | Edit | Always use HTTPS |
43
+ | Zone | Zone WAF | Edit | The rate limiting rule |
44
+ | Account | Registrar | Edit | Only when a domain is to be bought in the run |
45
+
46
+ Zone Resources: Include, All zones, so that a zone made in the run is covered. Account Resources: the one account. Client IP filtering: none. TTL: none, or a year. Continue to summary, Create Token, copy the secret once.
47
+
48
+ **How it reaches the agent.** Save it in a file named `.cf-token` in the run's folder (a file without an extension: in Notepad, "All files" as the type, so that it is not `.cf-token.txt`), and tell the agent; the agent reads it into the environment for each call and never prints it. The file is listed in the deployment repository's `.gitignore` from the first commit, and deleted at the end of the run on the person's word. A token pasted into the chat is written into the file with the agent's file tool and never repeated, and the person is told to make a new token once the run is over, since the chat kept a copy.
49
+
50
+ **Verify:**
51
+
52
+ ```sh
53
+ CLOUDFLARE_API_TOKEN=$(tr -d '\r\n ' < .cf-token)
54
+ curl -s https://api.cloudflare.com/client/v4/user/tokens/verify -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
55
+ curl -s https://api.cloudflare.com/client/v4/zones -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
56
+ curl -s https://api.cloudflare.com/client/v4/accounts -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
57
+ ```
58
+
59
+ `"status": "active"`, the zones the token sees (the domain among them, or none yet), and the account with its id. The file carries a carriage return on Windows; the `tr` strips it.
60
+
61
+ ## The git host
62
+
63
+ **The deployment repository.** The organization's deployment lives in a private repository on GitHub: the task definitions, the workflow that builds and deploys, the record. The agent makes it with the `gh` command signed in (`gh auth status`; `gh auth login` otherwise, which opens the browser for the person) under the owner the person names: their account, or an organization. Without `gh`, the person creates an empty private repository in the browser (New repository, private, no README) and gives its address, and the agent pushes to it.
64
+
65
+ **The OAuth app, for signing in with GitHub.** Once the console's address is known, the person, signed in to GitHub (checked 2026-10): Settings (under the avatar), Developer settings, OAuth Apps, New OAuth App (Register a new application, the first time).
66
+
67
+ - Application name: the board's name.
68
+ - Homepage URL: the console's address, `https://<hostname>`.
69
+ - Authorization callback URL: `https://<hostname>/auth/gh/callback`.
70
+ - Register application. Copy the **Client ID** into the chat (it is not secret). Generate a new client secret, and save it to the secrets file as `GITHUB_CLIENT_SECRET` (below), as the line the agent shows. A secret pasted into the chat instead is written into the file by the agent's file tool and never repeated, and the person generates a new one once the run is over, since the chat kept a copy; the new one goes in as "a secret rotated" of the record.
71
+
72
+ An organization-owned app is the same form under the organization's settings, Developer settings. No scopes are needed: the console asks only who the person is.
73
+
74
+ **The OAuth client, for signing in with Google.** In the Google Cloud console, a project of the organization's, Google Auth Platform (checked 2026-10): if the project has not registered with Google Auth yet, the Overview asks for the app's name, a support address and the audience (Internal, for a Workspace organization), once. Then Clients, Create client, Application type **Web application**, name it, under Authorized redirect URIs add `https://<hostname>/auth/google/callback`, Create. Copy the **Client ID** into the chat; the client secret is shown once: save it to the secrets file as `GOOGLE_CLIENT_SECRET`, as the line the agent shows (pasted instead: written to the file by the agent, never repeated, and replaced after the run, as with GitHub's). The Workspace domain, when everyone of it is a member, is the plan's `GOOGLE_WORKSPACE_DOMAIN`. Changes take from minutes to hours to be effective at Google.
75
+
76
+ ## The secrets file
77
+
78
+ What the person holds (a client secret) is written to a file outside any repository, in the shape of [secrets.example.json](../assets/secrets.example.json): `console-secrets.json` in the folder above the run's folder, with the generated and derived values the run adds to it. The run reads it to put each value in the parameter store, and deletes it at the end on the person's word. A value the person says `later` to leaves its provider out until it is set; the record names it. A provider the person did not choose has no line in it.