Comments (5)
Yes, I think we need some way to manage credentials that commands can run under.
One question is should plugin commands be able to access a global collection of credentials or should PoshBot separate them by plugin and only allow commands to access credentials associated with that plugin? The latter is more secure but potentially more cumbersome to manage. You may have multiple plugins that you've authored for your company and if you want to use the same credentials across plugins, you'd have to specify it in the configuration multiple times.
from poshbot.
Hmm - good question it might make sense to allow both, similar to statefuldata commands?
e.g.
Add-PoshBotRunAsCredential
or whatever system stores the credential might have something similar to -Scope
, allowing a user to specify if they want a credential to be available to everything, or a specific module.
For example:
- If
-Global
switch specified, any plugin can access it - If
-Module
[string[]]
specified, any plugin in the list can access it
from poshbot.
oh! if this is up for grabs, would be happy to help! some quick thoughts:
I see two general workflows:
- PoshBot admin wants to always run command ABC with credential XYZ, doesn't want to revamp internals of the plugin command. Design would likely require a command-to-credential mapping file
- PoshBot author wants to allow specifying a certain credential. Author will likely need to retrieve a PSCredential. Design would likely benefit from both (1) the option of a command-to-credential map, and (2) potentially the option to allow a user to specify the unique name of a credential to use
Might be over the top, just thinking off the top of my head
- Where / how to serialize credentials
- Typical DPAPI serialization to
$PoshBotContext.ConfigurationDirectory
or a subdirectory might make sense?
- Typical DPAPI serialization to
- What other information to include
- Username
- Password
- Optional? Unique Name (default to username, error and require force if existing found regardless of whether Name was provided or not)
- AllowedModules? Array, use
like
operator when evaluating whether a plugin can use it (*
for global) - Roles? Array, user calling command must be in this role to retrieve credential
- Description? Just for record keeping / details if desired
- Tags? A way for PoshBot authors to find a credential that their command needs, without forcing a user to specify a certain pre-determined name
- How to manage associating a command with a credential. Might need a config file mapping commands to credentials
Down the line, this could be used with data about a remote node to execute on, but IMHO it makes sense to keep that separate and let folks mix and match creds/remote details as needed. Or it could be combined. I see benefits / caveats to both...
Cheers!
from poshbot.
We may be able to reuse (with some tweaks) the existing functionality in PoshBot that allows plugin authors to specify that a command parameter by dynamically resolved from the bot configuration. The existing logic could probably be extended for plugin authors to declare that a command be run (as a job) with specific credentials that are stored under the PluginConfiguration
property of the bot configuration.
The way it currently works
PoshBot's Get-PoshBotConfiguration
and Save-PoshBotConfiguration
functions use Joel's Configuration module so it already handles serializing/deserialing credentials and secure strings (with the caveat that the user getting/saving the config must also be the user running PoshBot).
To use those values inside your plugin, you would decorate the parameter with [PoshBot.FromConfig()]
and PoshBot would look in the appropriate key (plugin name) and subkey (parameter name) and dynamically insert that value as a named parameter when executing the command as a job.
This doesn't solve running the entire command as another user but does provide a mechanism to pass secrets and other data to plugin commands that you can't (or don't want to) distribute with the plugin.
PoshBot.psd1
@{
###
# other bot properties omitted
###
PluginConfiguration = @{
MyModule = @{
Credential = (PSCredential "joeuser" "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000060ae863578849c4680a57d65f2994eff00000000020000000000106600000001000020000000cd8c90628fc9f7fd332869a0e30eec41cbje8c531618375f22bfa84a2a53e132000000000e80000000020000200000003b7027c1f5577bd36f7f9c87db7bb427f4808466758eb9a579e36be9bc49b3481000000092223e3261d78e6547ed0f799f5462eb400000008hpddfa3619fcc7b56bb2571b8cc9405740bf266e1fd8fc79b9nj1203ad9058d19a73eb75f5d977ef4478dc9f207f21e19c95affd1d44eca0b405f879e3c98nu")
}
}
}
MyModule.psm1
function Get-Foo {
[cmdletbinding()]
param(
[PoshBot.FromConfig()]
[parameter(mandatory)]
[string]$Credential
)
# Do something useful with $Credential
}
How it could work
This would be a breaking change to how plugin configuration is currently stored but we could modify the structure to resemble:
PoshBot.psd1
@{
###
# other bot properties omitted
###
PluginConfiguration = @{
# Global variables that any plugin can reference
Global = @{
SharedCred1 = (PSCredential "shared1" "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000060ae863578849c4680a57d65f2994eff00000000020000000000106600000001000020000000cd8c90628fc9f7fd332869a0e30eec41cbje8c531618375f22bfa84a2a53e132000000000e80000000020000200000003b7027c1f5577bd36f7f9c87db7bb427f4808466758eb9a579e36be9bc49b3481000000092223e3261d78e6547ed0f799f5462eb400000008hpddfa3619fcc7b56bb2571b8cc9405740bf266e1fd8fc79b9nj1203ad9058d19a73eb75f5d977ef4478dc9f207f21e19c95affd1d44eca0b405f879e3c98nu")
SharedCred2 = (PSCredential "shared2" "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000060ae863578849c4680a57d65f2994eff00000000020000000000106600000001000020000000cd8c90628fc9f7fd332869a0e30eec41cbje8c531618375f22bfa84a2a53e132000000000e80000000020000200000003b7027c1f5577bd36f7f9c87db7bb427f4808466758eb9a579e36be9bc49b3481000000092223e3261d78e6547ed0f799f5462eb400000008hpddfa3619fcc7b56bb2571b8cc9405740bf266e1fd8fc79b9nj1203ad9058d19a73eb75f5d977ef4478dc9f207f21e19c95affd1d44eca0b405f879e3c98nu")
}
# Variables only accessible to the plugin
MyModule = @{
Credential1 = (PSCredential "joeuser" "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000060ae863578849c4680a57d65f2994eff00000000020000000000106600000001000020000000cd8c90628fc9f7fd332869a0e30eec41cbje8c531618375f22bfa84a2a53e132000000000e80000000020000200000003b7027c1f5577bd36f7f9c87db7bb427f4808466758eb9a579e36be9bc49b3481000000092223e3261d78e6547ed0f799f5462eb400000008hpddfa3619fcc7b56bb2571b8cc9405740bf266e1fd8fc79b9nj1203ad9058d19a73eb75f5d977ef4478dc9f207f21e19c95affd1d44eca0b405f879e3c98nu")
MyOtherCredential = (PSCredential "sallysmith" "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000060ae863578849c4680a57d65f2994eff00000000020000000000106600000001000020000000cd8c90628fc9f7fd332869a0e30eec41cbje8c531618375f22bfa84a2a53e132000000000e80000000020000200000003b7027c1f5577bd36f7f9c87db7bb427f4808466758eb9a579e36be9bc49b3481000000092223e3261d78e6547ed0f799f5462eb400000008hpddfa3619fcc7b56bb2571b8cc9405740bf266e1fd8fc79b9nj1203ad9058d19a73eb75f5d977ef4478dc9f207f21e19c95affd1d44eca0b405f879e3c98nu")
}
}
}
}
You would then reference these variables in your plugin command by using the [PoshBot.BotCommand()]
and [PoshBot.FromConfig()]
custom attributes.
function Get-Foo {
# Run this command as a job using the 'SharedCred2' value from
# the global plugin configuration scope
[PoshBot.BotCommand(
CommandName = 'foo',
RunAs = 'SharedCred2',
Scope = 'Global'
)]
[cmdletbinding()]
param(
# Go get the 'Credential1` value from the plugin scope of the bot configuration
# 'Scope = 'Plugin' would be implicit
[PoshBot.FromConfig('Credential1')]
[pscredential]$Credential
# Go get the 'SharedCred1' value from the global plugin configuration scope
[PoshBot.FromConfig(
'SharedCred1',
Scope = 'Global'
)]
[pscredential]$SharedCredential
)
}
I like the idea of given the bot admin the ability to specify the credentials a command will run under without mucking with the plugin itself.
Perhaps another property could be added to the bot configuration like the following:
PoshBot.psd1
@{
# Control under what credential plugin commands are run under.
# Can specify individual commands or all commands in a plugin.
RunAs = @{
'MyPlugin:MyCommand' = 'SharedCred1`
'MyPlugin:Foo' = 'SharedCred2'
'MyOtherPlugin:*' = 'SharedCred1'
}
PluginConfiguration = @{
# Global variables that any plugin can reference
Global = @{
SharedCred1 = (PSCredential "shared1" "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000060ae863578849c4680a57d65f2994eff00000000020000000000106600000001000020000000cd8c90628fc9f7fd332869a0e30eec41cbje8c531618375f22bfa84a2a53e132000000000e80000000020000200000003b7027c1f5577bd36f7f9c87db7bb427f4808466758eb9a579e36be9bc49b3481000000092223e3261d78e6547ed0f799f5462eb400000008hpddfa3619fcc7b56bb2571b8cc9405740bf266e1fd8fc79b9nj1203ad9058d19a73eb75f5d977ef4478dc9f207f21e19c95affd1d44eca0b405f879e3c98nu")
SharedCred2 = (PSCredential "shared2" "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000060ae863578849c4680a57d65f2994eff00000000020000000000106600000001000020000000cd8c90628fc9f7fd332869a0e30eec41cbje8c531618375f22bfa84a2a53e132000000000e80000000020000200000003b7027c1f5577bd36f7f9c87db7bb427f4808466758eb9a579e36be9bc49b3481000000092223e3261d78e6547ed0f799f5462eb400000008hpddfa3619fcc7b56bb2571b8cc9405740bf266e1fd8fc79b9nj1203ad9058d19a73eb75f5d977ef4478dc9f207f21e19c95affd1d44eca0b405f879e3c98nu")
}
}
}
Sorry for the super long response.
It's late and I hope this makes sense 😫
I'm totally open to storing this data outside the main bot configuration if that makes sense as well.
from poshbot.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
from poshbot.
Related Issues (20)
- FunctionApp creation not working as expected HOT 2
- Recently having issues with 403 forbidden and 50001 Missing access errors. HOT 5
- How to define ChannelRules in Microsoft Teams channels? HOT 3
- Got Stuck with instructions for Microsoft Teams HOT 1
- Starting new discord bot instance gives method not found: no ForEach in PSCustomObject HOT 2
- Discord - cannot find user by discord handle with or without tag HOT 4
- Threads: Is it possible to execute command in thread and have results post back to it? HOT 1
- Slack Threads: Is it possible to execute command in thread and have results post back to it? HOT 2
- "CallingUserInfo":null for Teams Backend HOT 1
- IRC - PoshBot Backend
- PoshBot Powershell Gallery \r\n+ HOT 2
- Writing emojis to Discord backend converts to ascii HOT 1
- Scheduled Task not respecting Daylight Savings (DST) HOT 2
- Discord User-Agent required
- Discord Backend errors when connecting to server with "Stage" channel
- Poshbot - Teams Implementation output wraps at around 52 chars when using New-PoshbotCardResponse -text HOT 3
- Teams Backend stopped working HOT 5
- PoshBot not receiving webhook information in Teams console HOT 8
- Discord Slash Commands Support HOT 1
- Cannot connect to Discord backend HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from poshbot.